`

Attribute

 
阅读更多

1.特性是用来向程序集中添加额外的元数据信息,比如我们向程序集中的某个类添加了特性,那么在以后用反射读取该程序集的时候,我们就可以看到这些特性描述的信息了,而且在程序运行时你可以通过读取这些信息来影响程序如何运行。

2.特性与备注comment的区别就是备注是不会编译进元数据的,而特性是会编译成程序集的元数据的一部分的。

3.简单的说特性就是程序集中的一种附着物。

4.系统中的一些特性

5.自定义的attribute

           

//======水之真谛=======//
//    
上善若水,润物无声
  //
/*  http://blog.csdn.net/FantasiaX  */

using System;
namespace OysterAttributeSample
{
         class Oyster: System.Attribute                         // 
必需以System.Attribute类为基类

         {
                   // Kind
属性,默认值为
null
                   private string kind;
                   public string Kind
                   {
                            get { return kind; }
                            set { kind = value; }
                   }

                   // Age
属性,默认值为

                   private uint age;
                   public uint Age
                   {
                            get { return age; }
                            set { age = value; }
                   }

                   // 
值为nullstring是危险的,所以必需在构造函数中赋值

                   public Oyster(string arg)                                     // 定位参数
                   {
                            this.Kind = arg;
                   }
         }

         [Oyster("Thorny ", Age=3)]    // 3
年的多刺牡蛎附着在轮船(这是一个类)上。注意:对属性的赋值是在圆括号里完成的!

         class Ship
         {
                   [Oyster("Saddle")]          // 0
年的鞍形牡蛎附着在船舵(这是一个数据成员)上,Age使用的是默认值,构造函数的参数必需完整
                   public string Rudder;
         }

         class 
Program
         {
                   static void Main(string[] args)
                   {
                            // ... 
使用反射来读取Attribute
                   }
         }
}

Attribute作为编译器的指令

在C#中存在着一定数量的编译器指令,如:#define DEBUG, #undefine DEBUG, #if等。这些指令专属于C#,而且在数量上是固定的。而Attribute用作编译器指令则不受数量限制。比如下面的三个Attribute:

  • Conditional:起条件编译的作用,只有满足条件,才允许编译器对它的代码进行编译。一般在程序调试的时候使用。
  • DllImport:用来标记非.NET的函数,表明该方法在一个外部的DLL中定义。
  • Obsolete:这个属性用来标记当前的方法已经被废弃,不再使用了。

下面的代码演示了上述三个属性的使用:

 
#define DEBUG //这里定义条件
    
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
    
namespace AttributeDemo
{
   class MainProgramClass
   {
 
      [DllImport("User32.dll")]
      public static extern int MessageBox(int hParent, string Message, string Caption, int Type);
     
      static void Main(string[] args)
      {
         DisplayRunningMessage();
         DisplayDebugMessage();
     
         MessageBox(0,"Hello","Message",0);
     
         Console.ReadLine();
      }
     
      [Conditional("DEBUG")]
      private static void DisplayRunningMessage()
      {
         Console.WriteLine("开始运行Main子程序。当前时间是"+DateTime.Now);
      }
  
      [Conditional("DEBUG")]
      [Obsolete]
      private static void DisplayDebugMessage()
      {
         Console.WriteLine("开始Main子程序");
      }
   }
}  

如果在一个程序元素前面声明一个Attribute,那么就表示这个Attribute被施加到该元素上,前面的代码,[DllImport]施加到MessageBox函数上, [Conditional]施加到DisplayRuntimeMessage方法和DisplayDebugMessage方法,[Obsolete]施加到DisplayDebugMessage方法上。

根据上面涉及到的三个Attribute的说明,我们可以猜到程序运行的时候产生的输出:DllImport Attribute表明了MessageBox是User32.DLL中的函数,这样我们就可以像内部方法一样调用这个函数。

重要的一点就是Attribute就是一个类,所以DllImport也是一个类,Attribute类是在编译的时候被实例化的,而不是像通常的类那样在运行时候才实例化。Attribute实例化的时候根据该Attribute类的设计可以带参数,也可以不带参数,比如DllImport就带有"User32.dll"的参数。Conditional对满足参数的定义条件的代码进行编译,如果没有定义DEBUG,那么该方法将不被编译,读者可以把#define DEBUG一行注释掉看看输出的结果(release版本,在Debug版本中Conditional的debug总是成立的)。Obsolete表明了DispalyDebugMessage方法已经过时了,它有一个更好的方法来代替它,当我们的程序调用一个声明了Obsolete的方法时,那么编译器会给出信息,Obsolete还有其他两个重载的版本。大家可以参考msdn中关于的ObsoleteAttribute 类的描述

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics