特性(C#)

特性,是用来给代码添加额外信息的一种手段,我们通常是将特性标记到方法,类或者属性上,在使用的这些结构的时候,通过反射(reflection)这一非常高级的技术,获取它们通过特性标记的信息,从而进行某些特殊的处理。

和java的注解差不多

系统也给我们提供了一些特性,比如Serializable 标记一个可序列化的类,用法在成员上写个中括号。
它其实是省略了(),如果使用特性的其它的构造方法,显示声明即可:

  1. [Serializable]
  2. [Serializable("test")]
  3. class Sunshine{...}

自定义特性

编写自定义特性 创建自定义特性 (C#)

自定义特性,很简单,让一个类继承Attribute类即可,另外,自定义的特性,名称后缀约定是Attribute结尾,使用的时候这个后缀可以省略

  1. class MyAttribute : Attribute
  2. {
  3. private string name;
  4. private int age;
  5. public MyAttribute(string name,int age)
  6. {
  7. this.name = name;
  8. this.age = age;
  9. }
  10. public void GetName()
  11. {
  12. Console.WriteLine($"my name is {name}");
  13. }
  14. public void GetAge()
  15. {
  16. Console.WriteLine($"my age is {age}");
  17. }
  18. }
  1. [My("张三",13)]
  2. class Person
  3. {
  4. public Person(string name,int age)
  5. {
  6. this.Name = name;
  7. this.Age = age;
  8. }
  9. public string Name { get;private set; }
  10. public int Age { get;private set; }
  11. }

通过反射获取特性信息

使用反射访问特性 (C#)

  1. static void Main(string[] args)
  2. {
  3. //获取Person类的元数据
  4. Type type = typeof(Person);
  5. //获取类上面的全部特性
  6. IEnumerable<Attribute> attributes = type.GetCustomAttributes();
  7. foreach(var a in attributes)
  8. {
  9. //判断遍历的a是不是MyAttribute
  10. if (a is MyAttribute)
  11. {
  12. //转换类型
  13. MyAttribute my = a as MyAttribute;
  14. //反射创建对象
  15. Person person = (Person)Activator.CreateInstance(type, my.GetName(), my.GetAge());
  16. Console.WriteLine("反射出来的对象姓名:"+ person.Name);
  17. Console.WriteLine("反射出来的对象年龄:" + person.Age);
  18. }
  19. }
  20. }

指定特性用法

AttributeUsageAttribute特性放在自定义的特性上面,指定特性的用法。用法查看编写自定义特性

特性参数

许多特性都有参数,而这些参数可以是普通参数、命名参数。任何普通参数都必须按特定顺序指定并且不能省略,而命名参数是可选的且可以按任意顺序指定。首先指定普通参数。
例子:

  1. [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]

这是AttributeUsage特性,构造器普通参数就一个
image.png