Attribute使用详解

注意:Attribute翻译为特性,Property翻译为属性。本篇博客参考自多篇网络文章,不一一列举,但向那些博客的作者表示感谢.

   Attributes是一种新的描述信息,我们既可以使用attributes来定义设计期信息(例如 帮助文件,文档的URL),还可以用attributes定义运行时信息(例如,使XML中的元素与类的成员字段关联起来)。我们也可以用attributes来创建一个“自描述”的组件。Attribute与Java中的Annotation非常类似。

1、C# AttributeUsage有三个属性:
     ValidOn:定义特性该在何种程序实体前放置,比如AttributeTargets.Class,其他可能的值包括:

AttributeTargets.All
AttributeTargets.Assembly
AttributeTargets.Struct
AttributeTargets.Enum
AttributeTargets.Constructor
AttributeTargets.Method
AttributeTargets.Property
AttributeTargets.Field
AttributeTargets.Event
AttributeTargets.Interface
AttributeTargets.Parameter
AttributeTargets.Delegate


     AllowMultiple:定义特性能否在同一个程序实体前重复放置多次
     Inherited:特性能否被继承

2、使用实例:

[AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = false)]
public class HelpAttribute: DescriptionAttribute
{
   public HelpeAttribute(string desc): base(desc) {  }
    ...
}

public class Test
{
   [Help("test attribute")]
   public string TestAttribute { get;set; }
}

3、预定义的Attribute
     比如Obsolete特性:

[Obsolete("Old method, don't use", true]
public void oldMethod() { }

      它表示这是一个废弃的方法,不应该使用,第二个参数为true表示如果非要使用会发生编译错误

4、特性参数
     特性参数分为两种:一种是强制要求的,一种是可选的参数。
     强制要求的特性参数通过特性类的构造函数传递。
     可选的特性参数则不同。看实例:

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false]
public class HelpAttribute: Attribute
{
   public HelpAttribute(string desc)  // 强制参数
   {
      this.Desription = desc;
      this.Version = "No version defined"; // 可选参数
    }

    public string Description { get; }
    public string Version { get; set; } // 可选参数如果可以设置则必须有setter
}

    然后有下面的代码:

[Help("ClassA")]
[Help("ClassB", Version="1.0")]


    第一行的Version参数为默认的"No version defined",第二行代码的Version参数为1.0

5、特性类的参数类型
     特性类的参数类型限定为下面的类型中的一种:

boolbytechardoublefloatintlongshortstring、System.Type、object、枚举类型

6、特性标记
     如何让特性绑定到一个程序集?又如何绑定到一个方法的返回类型?
     我们可以使用特性标记,如:

[assembly: Help("blabla")]

     这个特性标记告诉编译器Help特性被绑定到整个程序集。可能的标识符包括:

assembly、module、type、method、property、event、field、param、return

     实例代码:

using System; 
using System.Reflection; 
using System.Diagnostics; 
//attaching Help attribute to entire assembly 
[assembly : Help("This Assembly demonstrates custom attributes creation and their run-time query.")] 
//our custom attribute class 
public class HelpAttribute : Attribute 
{
   // ...     
}


7、运行时查看Attribute
     通过反射,代码实例如下,很简单不多解释:
     一、查询程序集中的特性信息:

HelpAttribute HelpAttr; 
//Querying Assembly Attributes 
String assemblyName; 
Process p = Process.GetCurrentProcess(); 
assemblyName = p.ProcessName + ".exe"; 
Assembly a = Assembly.LoadFrom(assemblyName); 
foreach (Attribute attr in a.GetCustomAttributes(true)) 
{
   HelpAttr = attr as HelpAttribute; 
   if (null != HelpAttr) 
   { 
Console.WriteLine("Description of {0}:\n{1}",assemblyName,HelpAttr.Description); 
   } 
}

    二、查询类、方法和属性的特性信息:

Type type = typeof(AnyClass); 
HelpAttribute HelpAttr; 
//Querying Class Attributes 
foreach (Attribute attr in type.GetCustomAttributes(true)) 
{ 
   HelpAttr = attr as HelpAttribute; 
   if (null != HelpAttr) 
   { 
      Console.WriteLine("Description of AnyClass:\n{0}", HelpAttr.Description); 
   } 
}
 
//Querying Class-Method Attributes   
foreach(MethodInfo method in type.GetMethods()) 
{ 
   foreach (Attribute attr in method.GetCustomAttributes(true)) 
   {
      HelpAttr = attr as HelpAttribute; 
      if (null != HelpAttr) 
      {
         Console.WriteLine("Description of {0}:\n{1}",  method.Name,  HelpAttr.Description); 
       } 
    } 
}
 
//Querying Class-Field (only public) Attributes 
foreach(FieldInfo field in type.GetFields()) 
{ 
   foreach (Attribute attr in field.GetCustomAttributes(true)) 
   {
      HelpAttr= attr as HelpAttribute; 
      if (null != HelpAttr) 
      { 
         Console.WriteLine("Description of {0}:\n{1}", field.Name,HelpAttr.Description); 
       } 
    }
}

  

8、另外一个实例(带反射的应用)

public class ExcelTemplateModel
{
        [Description("城市")]
        public string City { get; set; }

        [Description("公司行业")]
        public string CompanyIndustry { get; set; }

        [Description("公司名称")]
        public string CompanyName { get; set; }
        ....
}

PropertyInfo[] properties = typeof(ExcelTemplateModel).GetProperties().
    Where(c => c.GetCustomAttributes(typeof(DescriptionAttribute), false).Length>0).ToList();
for(int i=0;i<propertys.Count;i++)
{
   ExcelTemplateModel item = new ExcelTemplateModel();
   properties[i].SetValue(item, value, null);
   excelList.Add(item);
}


其他细节内容请参考:http://msdn.microsoft.com/en-us/library/e8kc3626.aspx

原文地址:https://www.cnblogs.com/feichexia/p/2855358.html