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中特性的巧妙应用,改写!

原文地址:https://www.cnblogs.com/WeiGe/p/4207475.html