关于C#中的Attribute,MADN的定义为:公共语言运行时允许添加类似关键字的描述声明,叫做attributes, 它对程序中的元素进行标注,如类型、字段、方法和属性等。Attributes和Microsoft .NET Framework文件的元数据(metadata)保存在一起,可以用来向运行时描述你的代码,或者在程序运行的时候影响应用程序的行为。
我们可以编写自定义Attribute,来为代码添加自定义的描述,如作者信息,版本号,功能等,并通过反射来获取程序集中拥有对应Attribute的成员信息。
可以通过派生Attribute类来编写自定义特性,
using UnityEngine;
using System;
using System.Collections;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)]
public class MyVersionAttribute: Attribute
{
public string Author;
public string Description;
public string VersionCode;
public MyVersionAttribute(string author, string description, string versioncode)
{
this.Author = author;
this.Description = description;
this.VersionCode = versioncode;
}
public MyVersionAttribute(string description, string versioncode) : this("NoName", description, versioncode) { }
}
自定义特性类必须添加AttributeUsage特性,其构造函数包括一个AttributeTargets枚举型参数,表示允许将特性使用在哪些成员上,这里定义使用在类和结构体上,另外还有两个可选参数,AllowMultiple表示是否允许特性重复使用在同一成员上,Inherited表示是否允许特性可由派生类和重载函数继承。
接下来就可以在希望添加特性的成员上添加自定义特性了:
需要注意的是,添加自定义特性后,C#编译器发现这个成员使用了MyVersion作为名称的特性,会先将"Attribute"添加到MyVersion字符串后面,并在程序集中搜索这个类,即MyVersionAttribute类,也就是在特性中使用MyVersion和使用MyVersionAttribute是等同的,例如我们通常添加的可序列化特性System.Serializable实际对应的类为System.SerializableAttribute。
之后即可在特性后的圆括号内使用该特性的构造函数和填充可选参数,这里使用了public MyVersionAttribute(string author, string description, string versioncode)这个构造函数,而上面的AttributeUsage特性则使用了public AttributeUsageAttribute(AttributeTargets validOn)构造函数并填充了AttributeUsageAttribute类的Inherited 成员。
之后即可通过反射去获取程序集中的拥有该特性的成员信息:
public static void GetVersionInfo(string assemblyName)
{
Assembly assebly = Assembly.Load(assemblyName);
Type[] types = assebly.GetTypes();
foreach (Type t_type in types)
{
if (!t_type.IsClass)
continue;
var attributes = t_type.GetCustomAttributes(typeof(MyVersionAttribute), false);
foreach (var attribute in attributes)
{
MyVersionAttribute vAttribute = (MyVersionAttribute)attribute;
Debug.Log("类名:" + t_type.ToString());
Debug.Log("作者:" + vAttribute.Author);
Debug.Log("描述:" + vAttribute.Description);
Debug.Log("版本:" + vAttribute.VersionCode);
}
}
}