本篇介绍特性
文档中的介绍:
使用特性,可以有效地将元数据或声明性信息与代码(程序集、类型、方法、属性等)相关联。
将特性与程序实体相关联后,可以在运行时使用反射这项技术查询特性。
有点看不懂,我们可以结合一下代码来理解
在Unity中我们十分常用的一个特性就是SerializeField
[SerializeField]
private int i;
SerializeField可以让私有的成员变量在 Inspector 上进行显示。
所以特性就是我们常说的标签
在运行时,我们可以通过这些标签对标记的对象做一些特殊的操作。
(比如Untiy中SerializeField就是序列化对象,关联这个标签的对象将会被序列化)
特性的使用很简单,就是在需要关联特性的对象前加上标签
那么我们该如何自定义一个特性呢?
public class SetHellowAttribute : Attribute
{
string name;
public SetHellowAttribute (string name)
{
this.name = name;
}
public string GetName()
{
return name;
}
}
public class Test
{
[SetHellow("Attribute")]
public string Text;
}
这样我们就定义好了一个特性,但是
特性本身其实就是一个标签,这样只是为Text变量关联了一个标签
如果需要让它有实际作用,还需要用到反射的技术
//·通过特性获取对象
// 创建 Test 对象
var test= new Test();
// 获取 Test 的类型
var type = test.GetType();
// 获取所有标记 SetHellow 的成员变量
// 获取所有成员变量
var members = type.GetMembers();
var markedMembers =
members.Where(m => m.GetCustomAttributes(typeof(SetHellowAttribute), false).Length != 0);
// 设置 Hello
foreach (var markedMember in markedMembers)
{
var fieldInfo = markedMember as FieldInfo;
fieldInfo.SetValue(test, "Hello");
}
// 输出
Debug.Log(test.Text);
//·特性提供额外的信息与功能
//获取所有SetHellowAttribute特性
var attrs = System.Attribute.GetCustomAttributes(typeof(SetHellowAttribute));
//使用特性方法
foreach (System.Attribute attr in attrs)
{
if (attr is SetHellowAttribute)
{
SetHellowAttribute a = (SetHellowAttribute)attr;
//输出额外信息
Debug.Log(a.name);
//执行额外方法
a.LogWorld();
}
}
//output:
//Hello
//Attribute
//World