特性(Attribute)

Attribute非property(类的成员)

特性提供功能强大的方法以将声明信息与 C# 代码(类型、方法、属性等)相关联。

特性与程序实体关联后,即可在运行时使用名为“反射”的技术查询属性。

特性以两种形式出现:

  1. 一种是在公共语言运行库 (CLR) 中定义的特性。
  2. 另一种是可以创建的用于向代码中添加附加信息的自定义特性。此信息可在以后以编程方式检索。

特性具有以下特点:

  1. 特性可向程序中添加元数据。元数据是嵌入程序中的信息,如编译器指令或数据描述。
  2. 程序可以使用反射检查自己的元数据。
  3. 通常使用特性与 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);

 }

执行结果:

   

特性一般是和反射一起使用的,例如实体框架、工厂模式等。

posted @ 2011-06-11 09:49  澐飞扬  阅读(1079)  评论(8编辑  收藏  举报