特性实际上是一种附加数据,给一个类上或者内部的方法、属性等添加某个或一些特性相当于给这些内容附加上这些个特性的数据,从而能使得类中的这些数据被扩展了,附加上了额外的标记信息能够在后续的程序中被识别或者处理。
下面以新增一个自定义特性并将其输出到控制台中的程序为例:
首先建立一个Person类,结构如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyAttri { public class Person { [MyAttribute("身份证")] [SecAttribute("第二国际身份证")] public int Id { get; set; } [MyAttribute("姓名")] public string Name { get; set; } [MyAttribute("描述")] public string Description { get; set; } } }
在这个类中我分别添加了MyAttribute和SecAttribute属性,接下来是这两个属性的定义;
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyAttri { [AttributeUsage(AttributeTargets.Property)] public class MyAttribute: Attribute { public string Data { get; set; } public MyAttribute(string Data) { this.Data = Data; } } [AttributeUsage(AttributeTargets.Property)] public class SecAttribute : Attribute { public string Data { get; set; } public SecAttribute(string Data) { this.Data = Data; } } }
声明一个特性非常简单,主要就是该类需要继承自Attribute即可,AttributeUsage特性可以用来设置自定义特性可以挂载到哪些部分,我这里设置的是挂载到属性上;
特性一般包含一个字段或者属性,然后通过构造函数为该字段或者属性赋值,将其挂载到对应的目标对象上,我这里就是将特性挂载到了属性上,那么如何取出特性值呢?
代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace MyAttri { class Program { static void Main(string[] args) { Person p = new Person { Id = 1, Name = "Lee", Description = "一名学生" }; foreach (var prop in typeof(Person).GetProperties()) { Console.WriteLine(prop.Name); Console.WriteLine(prop.GetValue(p)); foreach (var att in prop.GetCustomAttributes(false)) { if (att is MyAttribute) { Console.WriteLine((att as MyAttribute).Data); } else if (att is SecAttribute) { Console.WriteLine((att as SecAttribute).Data); } } } Console.ReadKey(); } } }
首先通过反射的方式获取类中的所有属性对象,然后通过属性中的GetCustomAttributes方法获取所有特性,再通过for循环找到对应的特性,并将其内部携带的属性值提取出来,这样就可以在另外的程序中使用了。
输出结果如下:
End