注意: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、特性类的参数类型
特性类的参数类型限定为下面的类型中的一种:
bool、byte、char、double、float、int、long、short、string、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