星期四, 11月 17, 2005

[.Net].Net attribute

attribute, 用來為 class, method, parameters 貼上標籤,以便後續的應用.
所有的 attribute class 都要繼承 System.Attribute

class Class1Attribute: System.Attribute
{
}


使用的時候可以省略 Attribute
[Class1]
class Class2
{
}


打全名當然也是可以
[Class1Attribute]
class Class2
{
}


使用 xxx( yyy ) 時,attribute 的 constructor 會被套用,而 attribute class 裡的 property 會被自動認定為 named parameter.
class Class1Attribute: System.Attribute
{
private int _id;
private string _name;

public Class1Attribute( int id )
{
_id = id;
}

public string Name
{
get { return _name };
set { _name = value };
}
}
[Class1( 1, Name="This is a test" )]
class class2
{
}


也可以貼很多標籤上去
[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]
class Class1Attribute: System.Attribute
{
....
}
[Class1( 1, Name="This is a test" ), Class1( 2, Name="Test2" )]
class class2
{
}


但是要怎麼應用呢? 從 .Net framework documentation 裡的 sample, 大致上可以猜到.
using System;
using System.Reflection;

namespace CustomAttrCS {
// An enumeration of animals. Start at 1 (0 = uninitialized).
public enum Animal {
// Pets.
Dog = 1,
Cat,
Bird,
}

// A custom attribute to allow a target to have a pet.
public class AnimalTypeAttribute : Attribute {
// The constructor is called when the attribute is set.
public AnimalTypeAttribute(Animal pet) {
thePet = pet;
}

// Keep a variable internally ...
protected Animal thePet;

// .. and show a copy to the outside world.
public Animal Pet {
get { return thePet; }
set { thePet = Pet; }
}
}

// A test class where each method has its own pet.
class AnimalTypeTestClass {
[AnimalType(Animal.Dog)]
public void DogMethod() {}

[AnimalType(Animal.Cat)]
public void CatMethod() {}

[AnimalType(Animal.Bird)]
public void BirdMethod() {}
}

class DemoClass {
static void Main(string[] args) {
AnimalTypeTestClass testClass = new AnimalTypeTestClass();
Type type = testClass.GetType();
// Iterate through all the methods of the class.
foreach(MethodInfo mInfo in type.GetMethods()) {
// Iterate through all the Attributes for each method.
foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo)) {
// Check for the AnimalType attribute.
if (attr.GetType() == typeof(AnimalTypeAttribute))
Console.WriteLine(
"Method {0} has a pet {1} attribute.",
mInfo.Name, ((AnimalTypeAttribute)attr).Pet);
}
}
}
}
}


所以你可以看到,在貼上標籤以後,其實對 Class 本身來說沒啥作用,會認為有用的,是其他的 Class, 他們可以依據這些 Attribute 來作一些特定的處理.

這邊有一系列的文章,還提出了應用.

系列 2~4 介紹一個 sql generator 的範例.
系列 5~6 是一個比較深的範例,牽涉到 Remoting 的東西

.Net framework 內也預定了不少 Attribute,我覺得還蠻有用的.
例如: Conditional attribute

以下面的範例來說,如果 DEBUG 沒被定義,那麼 Class1.M() 將不會被執行.
這倒是一個不錯的debug方法
#define DEBUG
using System;
using System.Diagnostics;
class Class1
{
[Conditional("DEBUG")]
public static void M() {
Console.WriteLine("Executed Class1.M");
}
}
class Class2
{
public static void Test() {
Class1.M();
}
}


仔細想想也可以用來作版本控管喔...某版本可以用這個 method, 但是某版本不行....

還有就是 Obsolete, 可以用來指示 class 或 method 即將被淘汰

沒有留言: