介绍
特性(Attribute)是一种用于在程序运行时传递各种元素(例如类、方法、结构、枚举等)行为信息的声明性标签。使用特性可以将元数据(例如编译器指令、注释、描述、方法和类等信息)添加到程序中。
.Net Framework 提供了两种类型的特性,分别是预定义特性和自定义特性
特性具有以下属性:
- 使用特性可以向程序中添加元数据;
- 可以将一个或多个特性应用于整个程序、模块或者较小的程序元素(例如类和属性)中;
- 特性可以像方法和属性一样接受自变量;
- 程序可使用反射来检查自己的元数据或其他程序中的元数据。
语法
在要应用特性的元素前面用方括号[]来应用。如[Table("tableName")]
[特性名(指定信息参数)]
[Table("studentInfos")]
public class studentInfo
{
}
预定义特性
Net Framework 中提供了三个预定义的属性:
- AttributeUsage;
- Conditional;
- obsolete.
AttributeUsage
预定义特性 AttributeUsage 用来描述如何使用自定义特性类,用于自定义特性类前面,规定了特性可应用到的项目的类型。
格式如下:
[Attributeusage(
validon,
AllowMultiple = allowmultiple,
Inherited = inherited
)]
参数说明如下:
- 参数validon 用来定义特性可被放置的程序元素。它是枚举器 AttributeTargets 的值的组合。默认值是AttributeTargets.All;
- 参数 allowmultiple(可选参数)用来为该特性的 AowMulipl!e属性(property)提供一个布尔值,默认值为false(单用的),如。果为 true,则该特性是多用的;
- 参数inherited(可选参数)用来为该特性的Inherited属性(property)提供一个布尔值,默认为false(不被继承),如果为 true,则该特性可被派生类继承。
Conditional
预定义特性 Conditional 用来标记一个方法,它的执行依赖于指定的预处理标识符。根据该特性值的不同,在编译时会起到不同的效果
[Conditional("out")]
public void Print(string msg)
{
Console.writeLine(msg);
}
如果没有定义这个,就会忽略该方法。
obsolete
预定义特性 Obsolete 用来标记不应被使用的程序,您可以使用它来通知编译器放弃某个目标元素。
语法:[obsolete(message,iserror)]
[obsolete("Printout 已用",false)]
public void Printout(string msg)
{
Console.writeLine("输出消息:"+msg);
}
语法说明如下:
- 参数 message 是一个字符串,用来描述项目为什么过时以及应该使用什么替代;
- 参数 iserror是一个布尔值,默认值是false(编译器会生成一个警告),如果设置为true,那么编译器会把该项目的当作一个错误。
自定义特性
.Net Framework 允许创建自定义特性,自定义特性不但用于存储声明性的信息,还可以在运行时被检索。创建并使用自定义特性可以分为四个步骤:
- 声明自定义特性——特性名一般规定以Attribute结尾,派生于System.Attribute类;
- 构建自定义特性——定义属性或字段,创建构造函数、指定应用目标;
- 在目标程序上应用自定义特性——[特性名(参数值)];
- 通过反射访问特性。
最后一步涉及编写一个简单的程序来读取元数据以便查找各种符号。该程序应在运行时使用反射来访问特性
声明自定义特性
自定义特性应该继承 System.Attribute 类
public class RemarkAttribute:Attribute
{
}
构建自定义特性
给RemarkAttribute类定义属性或字段、构造函数,并指定应用目标。
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Constructor |
AttributeTargets.Field |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class RemarkAttribute:Attribute
{
public string description { get;set;}
public RemarkAttribute(string desp)
{
Description =desp;
}
}
应用自定义特性
通过把特性放置在紧挨着它的目标上面来应用该特性。
[Remark("名目信息")]
public class ItemInfo
{
[Remark("编号")]
public int ItemNo {get;set;}
[Remark("名称")]
public string ItemName { get; set;}
[Remark("类别")]
public ItemTypes ItemType {get;set;}
}
通过方法访问特性
在程序中,用反射的方式获取应用元素之上的特性标注的特性信息。
在AttributeHelper类中
//获取应用于类的注释信息
public static string GetclassDescription<T>()
{
string desp=nu1l;
Type type =typeof(T);
//获取应用在类上的Remark特性对象
RemarkAttribute attr =type.GetCustomAttribute<RemarkAttribute>();
if(attr != null])
{
desp = attr.Description;
return desp;
//获取应用于属性的注释信息
public static string GetPropertyDescription(this PropertyInfo p)
{
string desp=null;
//获取应用在属性上的Remark特性对象
RemarkAttribute attr =p.GetcustomAttribute<RemarkAttribute>();
if (attr != null)
{
desp = attr.Description
}
return desp;
}
//获取类和属性的注释
ItemInfo itemInfo01 = new ItemInfo()
{
ItemNo = no,
ItemName = itemName,
ItemType =itemType
}
//获取ItemInfo的注释
string itemRemark=AttributeHelper.GetclassDescription<ItemInfo>();
Type type=typeof(ItemInfo);
//获取各属性的注释
string noRemark=type.GetProperty("ItemNo").GetPropertyDescription();
string nameRemark=type.GetProperty("ItemName").GetPropertyDescription();
string typeRemark=type.GetProperty("ItemType").GetPropertyDescription():