特性,是用来给代码添加额外信息的一种手段,我们通常是将特性标记到方法,类或者属性上,在使用的这些结构的时候,通过反射(reflection)这一非常高级的技术,获取它们通过特性标记的信息,从而进行某些特殊的处理。
和java的注解差不多
系统也给我们提供了一些特性,比如Serializable 标记一个可序列化的类,用法在成员上写个中括号。
它其实是省略了(),如果使用特性的其它的构造方法,显示声明即可:
[Serializable][Serializable("test")]class Sunshine{...}
自定义特性
自定义特性,很简单,让一个类继承Attribute类即可,另外,自定义的特性,名称后缀约定是Attribute结尾,使用的时候这个后缀可以省略
class MyAttribute : Attribute{private string name;private int age;public MyAttribute(string name,int age){this.name = name;this.age = age;}public void GetName(){Console.WriteLine($"my name is {name}");}public void GetAge(){Console.WriteLine($"my age is {age}");}}
[My("张三",13)]class Person{public Person(string name,int age){this.Name = name;this.Age = age;}public string Name { get;private set; }public int Age { get;private set; }}
通过反射获取特性信息
static void Main(string[] args){//获取Person类的元数据Type type = typeof(Person);//获取类上面的全部特性IEnumerable<Attribute> attributes = type.GetCustomAttributes();foreach(var a in attributes){//判断遍历的a是不是MyAttributeif (a is MyAttribute){//转换类型MyAttribute my = a as MyAttribute;//反射创建对象Person person = (Person)Activator.CreateInstance(type, my.GetName(), my.GetAge());Console.WriteLine("反射出来的对象姓名:"+ person.Name);Console.WriteLine("反射出来的对象年龄:" + person.Age);}}}
指定特性用法
AttributeUsageAttribute特性放在自定义的特性上面,指定特性的用法。用法查看编写自定义特性
特性参数
许多特性都有参数,而这些参数可以是普通参数、命名参数。任何普通参数都必须按特定顺序指定并且不能省略,而命名参数是可选的且可以按任意顺序指定。首先指定普通参数。
例子:
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
这是AttributeUsage特性,构造器普通参数就一个
