2008年6月22日

C# Attributes 的使用

之前我在自家公司的產品,有導入自己製作的 ORM (Object Relational Mapping)的資料處理底層類別,在 Data Entity 上有使用到 Attributes 的觀念。它跟一般大家所講的類別的屬性(Property)是不一樣的,它可以在類別(Class)、方法(Function)、成員(Member)、屬性(Property)上去定義這些元素的用途、或一個資訊。有點像是這些元素的中繼資料(Meta Data),有興趣的朋友,可以到這個網站去了解一下,好了費話不多說,我就拿一個我在 MSDN 所看到的範例,來跟大家說明一下它可以作怎樣的運用:
using System;
using System.Reflection;

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

    // 一個自訂的 attribute 能允許目標物定義一個 pet (繼承 Attribute 類別)
    public class AnimalTypeAttribute : Attribute
    {
        // 當這個 attribute 被設定時,這個建構子(constructor)會被呼叫
        public AnimalTypeAttribute(Animal pet)
        {
            thePet = pet;
        }

        // 設定一個內部的變數
        protected Animal thePet;

        // 設定一個公開的屬性...
        public Animal Pet
        {
            get { return thePet; }
            set { thePet = Pet; }
        }
    }

    // 一個測試類別,在每個方法上都定義一個它屬於的 pet
    class AnimalTypeTestClass
    {
        [AnimalType(Animal.Dog)]
        public void DogMethod() { }

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

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

    //以下示範如何使用 attribute
    class DemoClass
    {
        //以下用 Console 模式下運作
        static void Main(string[] args)
        {
            AnimalTypeTestClass testClass = new AnimalTypeTestClass();
            Type type = testClass.GetType();
            
            // 將 AnimalTypeTestClass 的方法透過 foreach 全部取出
            foreach (MethodInfo mInfo in type.GetMethods())
            {
                // 將每一個 function 透過 foreach 取得 attribute 的集合
                foreach (Attribute attr in
                    Attribute.GetCustomAttributes(mInfo))
                {
                    // 檢查是否為 AnimalType 的資料型態如果是將它列印出來
                    if (attr.GetType() == typeof(AnimalTypeAttribute))
                        Console.WriteLine(
                            "Method {0} has a pet {1} attribute.",
                            mInfo.Name, ((AnimalTypeAttribute)attr).Pet);
                }

            }

            Console.In.ReadLine();
        }
    }
}

/*
 * 輸出結果:
 * Method DogMethod has a pet Dog attribute.
 * Method CatMethod has a pet Cat attribute.
 * Method BirdMethod has a pet Bird attribute.
 */

沒有留言:

張貼留言