首页 > 代码库 > C#秘密武器之特性

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 =http://www.mamicode.com/ 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中特性的巧妙应用,改写!

 

C#秘密武器之特性