通过C#反射获取类和类中属性的描述信息
自定义特性代码
[System.Serializable]
[System.AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
[System.Runtime.InteropServices.ComVisible(true)]
public class RecordAttribute : Attribute //注意:自定义特性名称后面需加Attribute
{
private string recordType; // 记录类型:更新/创建
private string author; // 作者
private DateTime date; // 更新/创建 日期
private string memo; // 备注
// 构造函数,构造函数的参数在特性中也称为“位置参数”。
public RecordAttribute(string recordType, string author, string date)
{
this.recordType = recordType;
this.author = author;
this.date = Convert.ToDateTime(date);
}
// 对于位置参数,通常只提供get访问器
public string RecordType { get { return recordType; } }
public string Author { get { return author; } }
public DateTime Date { get { return date; } }
// 构建一个属性,在特性中也叫“命名参数”
public string Memo
{
get { return memo; }
set { memo = value; }
}
}
我们发现在这个特性的定义上,又用了三个特性去描述它。这三个特性分别是:Serializable、AttributeUsage 和 ComVisible。Serializable特性我们前面已经讲述过,ComVisible简单来说是“控制程序集中个别托管类型、成员或所有类型对 COM 的可访问性”(微软给的定义)。这里我们应该注意到:特性本身就是用来描述数据的元数据,而这三个特性又用来描述特性,所以它们可以认为是“元数据的元数据”(元元数据:meta-metadata)。
AllowMutiple 属性用于设置该特性是不是可以重复地添加到一个类型上(默认为false),
Inherited 就更复杂一些了,假如有一个类继承自我们的DemoClass,那么当我们将RecordAttribute添加到DemoClass上时,DemoClass的子类也会获得该特性。而当特性应用于一个方法,如果继承自该类的子类将这个方法覆盖,那么Inherited则用于说明是否子类方法是否继承这个特性。
定义一个测试用类
[Record("ITone", "ITone", "2018-8-8")]
[Record("ITone", "ITone", "2018-8-8", Memo = "测试仪")]
[Record("ITone", "ITone", "2018-8-8")]
public class TestClass
{
[Description("中文名字")]
public string Name { get; set; }
[Description("描述用户的ID")]
public string UserID { get; set; }
[Obsolete("请使用新的方法 ")]
public void SendMsg()
{
Console.Write("xxxxx");
}
public void SendMsg(string ms)
{
Console.Write("x1222xxxx");
}
}
测试代码
static void Main(string[] args)
{
Type t = typeof(TestClass);
Object[] records = t.GetCustomAttributes(typeof(RecordAttribute), false);
foreach (RecordAttribute record in records)
{
Console.WriteLine(" 类型:{0}", record.RecordType);
Console.WriteLine(" 作者:{0}", record.Author);
Console.WriteLine(" 日期:{0}", record.Date.ToShortDateString());
if (!String.IsNullOrEmpty(record.Memo))
{
Console.WriteLine(" 备注:{0}", record.Memo);
}
}
//获取这个对象的所有公共属性
PropertyInfo[] zh = t.GetProperties();
foreach (var item in zh)
{
//获取属性的描述
Object[] obs= item.GetCustomAttributes(typeof(DescriptionAttribute),false);
foreach (DescriptionAttribute record in obs)
{
Console.WriteLine(" 类型:{0}", record.Description);
}
}
//通过反射来创建一个实体
TestClass ass = (TestClass)Assembly.GetExecutingAssembly().CreateInstance("Demo_One.TestClass");
ass.SendMsg("");
}