1. 程式人生 > >[C#] Attribute

[C#] Attribute

getc 名稱空間 -1 etc 反射 strong 什麽是 tex issues

什麽是Attribute?我們為什麽需要Attribute?

Attribute是一段附加信息,該信息可以附加在方法,類,名稱空間,程序集上。例如下面的例子中,將Method1設為“Obsolete”屬性。

    public class MyClass
    {
        [Obsolete]
        public void Method1()
        {
        }

        public void NewMethod()
        {
        }
    }

我們在代碼中調用Method1,這個方法,
技術分享

簡單的說,Attribute其實沒有做任何代碼相關的工作,只是給開發者一段直觀的提示信息。在“Obsolete” 屬性上,如果你需要給開發者更多信息。例如:

        [Obsolete("Please use NewMethod")]
        public void Method1()
        {
        }

如果需要限制開發者使用Method1,可以在Obsolete屬性中,傳遞“true”,代碼如下:

        [Obsolete("Please use NewMethod", true)]
        public void Method1()
        {
        }

此時再調用Method1,則編譯時直接報錯,而不是一個Warning信息。
技術分享

怎麽創建自定義Attribute

上述代碼中使用的Obsolete屬性是系統提供的。自定義Attribute只需要繼承Attribute類即可。例如:

    public class HelpAttribute : Attribute
    {
        public string HelpText { get; set; }
    }

    [Help(HelpText ="This is a class")]
    public class Customer
    {
        private string _customerCode;

        [Help(HelpText = "This is a property
")] public string CustomerCode { get { return _customerCode; } set { _customerCode = value; } } [Help(HelpText ="This is a method")] public void Add() { } }

自定義了一個HelpAttribute,然後將它應用在類/方法/屬性上面。

是否可以限制一個自定義Attribute只應用在方法或者屬性上面?

對HelpAttribute類進行如下修改即可,

    [AttributeUsage(AttributeTargets.Method)]
    public class HelpAttribute : Attribute
    {
        public string HelpText { get; set; }
    }

在HelpAttribute上面添加AttributeUsage屬性,將AttributeTargets設置為Method即可。AttributeTargets是一個枚舉類型,更多信息:

https://msdn.microsoft.com/en-us/library/system.attributetargets(v=vs.110).aspx

除了可以描述一段信息之外,Attribute還可以做什麽?

例如下面的例子,限制一個字段長度的Attribute。定義一個CheckAttribute,並在Customer的CustomerCode的長度,

    [AttributeUsage(AttributeTargets.Property)]
    public class CheckAttribute : Attribute
    {
        public int MaxLength { get; set; }
    }

    public class Customer
    {
        private string _customerCode;

        [Check(MaxLength = 10)]
        public string CustomerCode
        {
            get { return _customerCode; }
            set { _customerCode = value; }
        }

        [Help(HelpText ="This is a method")]
        public void Add()
        {

        }
    }

下面使用反射(Reflection)來讀取Attribute的值,並做校驗,

    Customer obj = new Customer();
    obj.CustomerCode = "12345678901";

    // Reflect
    // Get the type of the object
    Type type = obj.GetType();

    // Loop through all properties
    foreach (PropertyInfo p in type.GetProperties())
    {
        foreach (Attribute atr in p.GetCustomAttributes(false))
        {
            CheckAttribute c = atr as CheckAttribute;

            if(c != null)
            {
                if(p.Name == "CustomerCode")
                {
                    // Do the length check and raise exception accordingly
                    if(obj.CustomerCode.Length > c.MaxLength)
                    {
                        throw new Exception("Max length issues.");
                    }
                }
            }
        }
    }

自定義Attribute是否可以被繼承?

可以。例如,自定義一個CheckExAttribute繼承自CheckAttribute

如果不想被其它Attribute繼承,使用Inherited =false標記即可,

    [AttributeUsage(AttributeTargets.Property,Inherited =false)]
    public class CheckAttribute : Attribute
    {
        public int MaxLength { get; set; }
    }

如果一個屬性只想被調用一次,可以使用AllowMultiple=false

    [AttributeUsage(AttributeTargets.Property,AllowMultiple=false)]
    class Check : Attribute
    {
        public int MaxLength { get; set; }
    }

感謝您的閱讀!

[C#] Attribute