特性(Attribute)
Attribute非property(类的成员)
特性提供功能强大的方法以将声明信息与 C# 代码(类型、方法、属性等)相关联。
特性与程序实体关联后,即可在运行时使用名为“反射”的技术查询属性。
特性以两种形式出现:
- 一种是在公共语言运行库 (CLR) 中定义的特性。
- 另一种是可以创建的用于向代码中添加附加信息的自定义特性。此信息可在以后以编程方式检索。
特性具有以下特点:
- 特性可向程序中添加元数据。元数据是嵌入程序中的信息,如编译器指令或数据描述。
- 程序可以使用反射检查自己的元数据。
- 通常使用特性与 COM 交互。
先看一个例子:
[System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "MessageBoxW")] public static extern int MessageBoxW([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWnd, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpText, [System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string lpCaption, uint uType); static void Main(string[] args) { Console.WriteLine(MessageBoxW(IntPtr.Zero, "确定吗?", "提示", 1)); }
看一下执行结果:
特性类实例化时需要放在括号“[ ]”中,语法:
[attributeClass(定位参数1,… 命名参数1,…)]
定位参数和相应特征类的实例构造器紧密相关——构造器提供了什么样的参数构造方式,位置参数就对应什么样的形式。位置参数不可省略,但如果特征类提供了无参数的构造器,那就另当别论。
命名参数对应着特征类的实例公有域或实例特性,但它在实例化的时候并非必须,可以省略。
位置参数和指定参数只可以为如下数据类型 :
- 基本数据类型中的值类型:整形,浮点类型,字符, Bool
- System.object, System.Type,System.string
- 枚举类型
- 以上任何类型的一维数组
通过定义一个特性类,可以创建您自己的自定义特性。该特性类直接或间接地从System. Attribute 派生,有助于方便快捷地在元数据中标识特性定义。假设您要用编写类或结构的程序员的名字标记类和结构。
例 子:
通过定义一个特性类,可以创建您自己的自定义特性。该特性类直接或间接地从System. Attribute 派生,有助于方便快捷地在元数据中标识特性定义。假设您要用编写类或结构的程序员的名字标记类和结构。
示例:
//Author属性只能用于类和结构,AllowMultiple是否允许多次用属性,Inherited是这个属性是滞延续到子类。 [AttributeUsage(AttributeTargets.Class|AttributeTargets.Property,AllowMultiple=true,Inherited=true)]
public class AuthorAttribute : Attribute
{
string name;//作者
public double version;//版本
public string Name
{
get
{
return name;
}
}
public AuthorAttribute(string name)
{
this.name = name;
this.version = 1.0;
}
}
[AuthorAttribute("张三", version = 3.5)]//张三是Author的构造函数的参数,version是字段
class ZCL
{ }
看一下特性是怎么使用的:
Type type = typeof(ZCL);
Console.WriteLine(type);
foreach(object o in type.GetCustomAttributes(true))
{
Console.WriteLine("作者:"+((AuthorAttribute)o).Name+" 版本:"+((AuthorAttribute)o).version);
}
执行结果:
特性一般是和反射一起使用的,例如实体框架、工厂模式等。