Attributes in C# 笔记

使用预定义的Attribute

using System;
public class AnyClass 
{
[Obsolete("Don't use Old method, use New method", true)]
static void Old( ) { }

static void New( ) { }

public static void Main( ) 
{
Old( );
}
}

这里告诉编译器Old这个item是过时的,编译时会将它作为一个错误处理,并且显示信息:"别用老方法了,用新的方法吧".

自定义Attribute

只需要从System.Attribute类派生出来就可以了。

using System;
public class HelpAttribute : Attribute
{
}

类的名字一般以Attribute作为词缀,但是不加也可以。当你使用Help进行修饰的时候,编译器会在Attribute派生类里寻找Help类,如果没有,就自动添加Attribute词缀,即:编译器会在子类里寻找HelpAttribute类。

接下来就是将HelpAttribute进行实现并装饰其他的类了。

using System;
public class HelpAttribute : Attribute
{
 public HelpAttribute(String Descrition_in)
 {
   this.description = Description_in;
 }
 protected String description;
 public String Description 
 {
   get 
   {
     return this.description;
   } 
 } 
}

[Help(
"this is a do-nothing class")] public class AnyClass { }

AttributeUsage是一个特别的类,它修饰自定义的Attribute类,主要是帮助我们定义如何使用attribute,它有三个属性:
ValidOn可以指明attribute可以放在什么地方;AllowMultiple指明一个attribute是否可以多次放在同一个实体里面,Inherited指明这个attribute是否会在所修饰的类
的子类里面出现。

using System;
[AttributeUsage(AttributeTargets.Class), AllowMultiple = false, 
Inherited = false ]
public class HelpAttribute : Attribute
{
     public HelpAttribute(String Description_in)
    {
        this.description = Description_in;
    }
    protected String description;
    public String Description
    {
        get 
        {
        return this.description;
        } 
    } 
}     

这个例子说明,HelpAttribute只能修饰class,并且只能放一次,不能被继承。因此,下面的情况都是错的:

[Help("this is a do-nothing class")]
public class AnyClass
{
  [Help("this is a do-nothing method")] //只能修饰class,不能修饰方法
  public void AnyMethod()
  {
  }
} 

[Help("this is a do-nothing class")]
[Help("it contains a do-nothing method")] //只能修饰一次而已,这里修饰了两次
public class AnyClass
{
  public void AnyMethod()
  {
  }
}

AttributeTargets包括:

  • Assembly,
  • Module,
  • Class,
  • Struct,
  • Enum,
  • Constructor,
  • Method,
  • Property,
  • Field,
  • Event,
  • Interface,
  • Parameter,
  • Delegate,
  • All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Interface | Parameter | Delegate,
  • ClassMembers = Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface

Positional Parameter和Named Parameter

Positional参数是构造器的参数,而且是强制要有的,相反,Named参数是可选的。
对于Named参数,如果要使用它,必须要定义一个set方法。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false,
Inherited = false)]
public class HelpAttribute : Attribute
{
  public HelpAttribute(String Description_in)
  {
    this.description = Description_in;
    this.verion = "No Version is defined for this class";
  }
  protected String description;
  public String Description
  {
    get 
    {
      return this.description;
    }
  }
  protected String version;
  public String Version
  {
    get 
    {
      return this.version;
    }
    //if we ever want our attribute user to set this property, 
    //we must specify set method for it 
    set 
   {
      this.verion = value;
   }
  }
}

[Help("This is Class1")]
public class Class1
{
}

[Help("This is Class2", Version = "1.0")]
public class Class2
{
}

[Help("This is Class3", Version = "2.0", 
Description = "This is do-nothing class")]
public class Class3
{
}

这里的Description就是Positional参数,而Version就是Named参数。
Class 1和Class 2 都能正常输出,Class 3由于没有给Description的set方法,因此会报错Description为只读。

Attribute identifier

attribute identifier是用来标注attribute作用在什么上面,比如是方法上,类型上,返回值上还是全部的程序集上。
所有可能的值包括:

  • assembly
  • module
  • type
  • method
  • property
  • event
  • field
  • param
  • return

于是就可以用[assembly: Help("this a do-nothing assembly")]指明Help作用在整个程序集上。

在运行时使用反射的方法查找一个类(或者一个方法,一个字段,整个程序集)上面所有的attribute

using System;
using System.Reflection;
using System.Diagnostics;

//attaching Help attribute to entire assembly
[assembly : Help("This Assembly demonstrates custom attributes 
creation and their run-time query.")]

//our custom attribute class
public class HelpAttribute : Attribute
{
  public HelpAttribute(String Description_in)
  {
    //
    // TODO: Add constructor logic here
    this.description = Description_in;
  }
  protected String description;
  public String Description
  {
    get 
    {
     return this.deescription;
    } 
  } 
}

//attaching Help attribute to our AnyClass
[HelpString("This is a do-nothing Class.")]
public class AnyClass
{
  //attaching Help attribute to our AnyMethod
  [Help("This is a do-nothing Method.")]
  public void AnyMethod()
  {
  }
  //attaching Help attribute to our AnyInt Field
  [Help("This is any Integer.")]
  public int AnyInt;
}

class QueryApp
{
  public static void Main()
  {
  HelpAttribute HelpAttr;

  //Querying Assembly Attributes
  String assemblyName;
  Process p = Process.GetCurrentProcess();
  assemblyName = p.ProcessName + ".exe";

  Assembly a = Assembly.LoadFrom(assemblyName);

  foreach (Attribute attr in a.GetCustomAttributes(true))
  {
    HelpAttr = attr as HelpAttribute;
    if (null != HelpAttr)
   {
    Console.WriteLine("Description of {0}:\n{1}", 
    assemblyName,HelpAttr.Description);
   }
  }

  Type type = typeof(AnyClass);


  //Querying Class Attributes
  foreach (Attribute attr in type.GetCustomAttributes(true))
  {
    HelpAttr = attr as HelpAttribute;
    if (null != HelpAttr)
    {
     Console.WriteLine("Description of AnyClass:\n{0}", 
  HelpAttr.Description);
     }
    }
  //Querying Class-Method Attributes 
  foreach(MethodInfo method in type.GetMethods())
  {
    foreach (Attribute attr in method.GetCustomAttributes(true))
   {
     HelpAttr = attr as HelpAttribute;
     if (null != HelpAttr)
    {
    Console.WriteLine("Description of {0}:\n{1}", 
method.Name, 
HelpAttr.Description);
     }
   }
}
//Querying Class-Field (only public) Attributes
foreach(FieldInfo field in type.GetFields())
{
  foreach (Attribute attr in field.GetCustomAttributes(true))
  {
   HelpAttr= attr as HelpAttribute;
   if (null != HelpAttr)
   {
   Console.WriteLine("Description of {0}:\n{1}",
   field.Name,HelpAttr.Description);
   }
  }
}

}
}

原文地址:Attributes in C#(CodeProject)

posted @ 2012-11-10 15:44  cubika  阅读(181)  评论(0编辑  收藏  举报