zoukankan      html  css  js  c++  java
  • C#秘密武器之特性

    一、概述

    Attribute说白了就是一个类而已,里边一般含有一些附加信息,或者一些特殊的处理逻辑,以便告诉编译器应用该特性的东东是个奇葩,需要特殊对待!

    二、使用时的注意事项

    2.1. Attribute是一个类,必须继承自System.Attribute

    2.2 Attribute命名规范
    Attribute命名一般以Attribute结尾, 但是在具体使用时候,可以省去Attribute这一后缀。加入定义了一个HelperAttribute, 具体使用的时候,可以这样写[Helper].

    2.3 Attribute的使用限制
    Attribute类在定义的时候,可以指定这个Attribute的应用范围,AttributeTargets枚举就列出了可以指定的范围,可以是class, field等;AllowMutiple为true或者false,意思就是是否让该特性在某个地方重复使用(比如在某一个类上使用多次);Inherited为true或者false,意思就是该特性是否会被应用该特性的类的子类继承。

    2.4 Attribute中的参数赋值

    位置参数(Attribute构造函数的参数):必填,且顺序要一致!

    命名参数(Attribute中的其他字段或者属性):在使用时可以省略!

    三、自定义一个Attribute并读取其值

    举个栗子:

    [AttributeUsage(AttributeTargets.Class, AllowMutiple=true, Inherited=false)]
     public class BookAttribute:Attribute
        {
            
    public string Msg { get; set; }
            
    public double Version = 1.0;
            
    public MyFirstAttribute(string msg)
             {
                 Msg
    = msg;
             }
        }

    通过反射获取Attribute相关信息:

    namespace TestAttribute
      {
    //多次使用特性类

    [Book("人民邮电")] [Book("北京")]   class BookInfo   {    public string bookinfo = "图书信息";    //构造函数   public BookInfo()   {   }   }   }
    static void Main(string[] args)
            {
                BookInfo bookinfo = new BookInfo();
                MemberInfo typeinfo = typeof(BookInfo);
              object[] bookarr= typeinfo.GetCustomAttributes(typeof(BookAttribute), false);
          if (bookarr.GetLength(0) != 0)
                {
                    BookAttribute bookattribute1 = (BookAttribute)bookarr[0];
                      BookAttribute bookattribute2 = (BookAttribute)bookarr[1];
                      Console.WriteLine(bookinfo.bookinfo);
                    Console.WriteLine("出版社为:" + bookattribute1.Msg+ "城市为:" + bookattribute2.Msg);
                    Console.ReadKey();
                }
            }

    四、学会使用一些.NET内置特性

    举个栗子:

    System.ObsoleteAttribute:告诉编译器某个方法已经过时,然后当编译器发现程序中有地方在使用这个用Obsolete标记过的方法时,就会给出一个警告信息。

    public class TestClass
    {
    // 添加Obsolete特性
    [Obsolete("请使用新的SendMsg(Message msg)重载方法")]
    public static void ShowMsg()
    {
    Console.WriteLine("这是旧的SendMsg()方法");
    }
    }
    private void button1_Click(object sender, EventArgs e)
    {
    TestClass.ShowMsg();
    }

    现在运行这段代码,我们会发现编译器给出了一个警告!

    五、特性在枚举上的应用

    enum Gender
    {
           [Description(“男”)]
           Man,
    
           [Description(“女”)]
           Woman
    };
    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Reflection;  
       
    namespace MyTools  
    {  
        /// <summary>   
        /// 枚举帮助类   
        /// </summary>   
       public static class EnumHelper  
        {  
           /// <summary>   
           /// 获取枚举项的Attribute   
           /// </summary>   
           /// <typeparam name="T">自定义的Attribute</typeparam>   
          /// <param name="source">枚举</param>   
          /// <returns>返回枚举,否则返回null</returns>   
           public static T GetCustomAttribute<T>(Enum source) where T : Attribute  
           {  
               Type sourceType = source.GetType();  
               string sourceName = Enum.GetName(sourceType, source);  
               FieldInfo field = sourceType.GetField(sourceName);  
               object[] attributes = field.GetCustomAttributes(typeof(T), false);  
               foreach (object attribute in attributes)  
               {  
                  if (attribute is T)  
                       return (T)attribute;  
               }  
              return null;  
           }  
       
            /// <summary>   
           ///获取DescriptionAttribute描述   
           /// </summary>   
           /// <param name="source">枚举</param>   
           /// <returns>有description标记,返回标记描述,否则返回null</returns>   
            public static string GetDescription(this Enum source)  
            {  
               var attr = GetCustomAttribute<System.ComponentModel.DescriptionAttribute>(source);  
               if (attr == null)  
                  return null;  
       
               return attr.Description;  
            }
    
            public static EnumT GetValueByDescription<EnumT>(string description)
            {
                var type = typeof(EnumT);
                if (!type.IsEnum)
                    throw new ArgumentException("This method is destinated for enum types only.");
                foreach (var enumName in Enum.GetNames(type))
                {
                    var enumValue = Enum.Parse(type, enumName);
                    if (description == ((Enum)enumValue).GetDescription())
                        return (EnumType)enumValue;
                }
                throw new ArgumentException("There is no value with this description among specified enum type values.");
            }
      
       }  
    }  

    使用方法:

    Gender.Man.GetDescription()

    注意MVC中特性的巧妙应用,改写!

  • 相关阅读:
    将Nginx添加到windows服务中
    springboot使用redis管理session
    GIT常用命令
    阻止360、谷歌浏览器表单自动填充
    谈谈对Spring IOC的理解
    同一个Nginx服务器同一端口配置多个代理服务
    LeetCode 653. Two Sum IV
    109. Convert Sorted List to Binary Search Tree(根据有序链表构造平衡的二叉查找树)
    108. Convert Sorted Array to Binary Search Tree(从有序数组中构造平衡的BST)
    LeetCode 236. Lowest Common Ancestor of a Binary Tree(二叉树求两点LCA)
  • 原文地址:https://www.cnblogs.com/WeiGe/p/4207475.html
Copyright © 2011-2022 走看看