[C#] Attribute
什麽是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