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 來作一些特定的處理.
這邊有一系列的文章,還提出了應用.
- 博客园 – dudu – Attribute在.net编程中的应用(一)
- 博客园 – dudu – Attribute在.net编程中的应用(二)
- 博客园 – dudu – Attribute在.NET编程中的应用(三)
- 博客园 – dudu – Attribute在.NET编程中的应用(四)
- 博客园 – dudu – Attribute在.NET编程中的应用(五)
- 博客园 – dudu – Attribute在.NET编程的应用(六)
系列 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 即將被淘汰