1 namespace Common.Library.ChangeRecord 2 { 3 /// <summary> 4 /// desc:記錄 修改記錄 的特性 5 /// </summary> 6 [AttributeUsage((AttributeTargets)6140, AllowMultiple = true, Inherited = false)] 7 public class RecordAttribute : Attribute 8 { 9 private RecordType recordType; // 記錄類型:更新/建立 10 private string author; // 做者 11 private DateTime date; // 更新/建立 日期 12 private string mark; // 備註 13 14 // 構造函數,構造函數的參數在特性中也稱爲「位置參數」。 15 public RecordAttribute(RecordType recordType, string author, string date) 16 { 17 this.recordType = recordType; 18 this.author = author; 19 this.date = Convert.ToDateTime(date); 20 } 21 22 // 對於位置參數,一般只提供get訪問器 23 public RecordType RecordType { get { return recordType; } } 24 public string Author { get { return author; } } 25 public DateTime Date { get { return date; } } 26 27 // 構建一個屬性,在特性中也叫「命名參數」 28 public string Mark 29 { 30 get { return mark; } 31 set { mark = value; } 32 } 33 } 34 /// <summary> 35 /// 記錄類型 枚舉 36 /// </summary> 37 public enum RecordType 38 { 39 Add, 40 Modify 41 } 42 }
NOTE:注意構造函數的參數 date,必須爲一個常量、Type類型、或者是常量數組,因此不能直接傳遞DateTime類型。
這個類看上去和普通的類沒有和大區別,顯然不能它由於名字後面跟了個Attribute就搖身一變成了特性。它知足了,咱們前面所說的自定義特性的要求,繼承了System.Attribute類、用AttributeUsage特性限制了應用的目標、有屬性和構造函數等。
下面是應用特性:
1 namespace Common.Library 2 { 3 [Record(RecordType.Add, "Joey", "2013-07-23")] 4 [Record(RecordType.Modify, "Joey", "2013-07-23", Mark = "測試")] 5 [Record(RecordType.Modify, "Joey", "2013-07-24", Mark = "修改bug")] 6 public class TestAttribute 7 { 8 [Record(RecordType.Add, "Joey", "2013-07-23", Mark = "測試特性附加到方法上")] 9 [Record(RecordType.Add, "Shovy", "2013-07-25", Mark = "修改此方法")] 10 public void MyMethod() 11 { 12 } 13 14 [Record(RecordType.Add, "Joey", "2013-07-23", Mark = "方法2")] 15 [Record(RecordType.Add, "Zoe", "2013-07-25", Mark = "修改方法2")] 16 public void Method2() 17 { 18 } 19 } 20 }
1 namespace ConsoleApp 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 TestAttribute testClass = new TestAttribute(); 8 Type type = testClass.GetType(); //獲取要得到自定義特性的類型的Type對象 9 Attribute[] myAttributes = Attribute.GetCustomAttributes(type);//獲取類型上添加的自定義特性 10 Console.WriteLine("類型{0}上應用的Record特性:", type.ToString()); 11 Console.WriteLine(); 12 foreach (Attribute item in myAttributes) 13 { 14 if (item.GetType() == typeof(RecordAttribute)) //只打印咱自定義的特性 15 { 16 RecordAttribute attr = (RecordAttribute)item; 17 Console.WriteLine(" 類型:{0},更改人:{1},更改時間:{2},備註:{3}", attr.RecordType, attr.Author, attr.Date.ToString("yyyy-MM-dd"), attr.Mark); 18 } 19 } 20 Console.WriteLine(); 21 Console.WriteLine("類型{0}的方法上應用的Record特性:", type.ToString()); 22 Console.WriteLine(); 23 foreach (MethodInfo mInfo in type.GetMethods()) //遍歷該類型的全部方法 24 { 25 if (Attribute.IsDefined(mInfo, typeof(RecordAttribute))) //只有在方法上附加了屬性,才遍歷 26 { 27 Console.WriteLine(" 類型{0}的{1}方法上的Record特性", type.ToString(), mInfo.ToString()); 28 Console.WriteLine(); 29 foreach (Attribute item in Attribute.GetCustomAttributes(mInfo)) //遍歷方法上的 特性 30 { 31 if (item.GetType() == typeof(RecordAttribute)) 32 { 33 RecordAttribute attr = (RecordAttribute)item; 34 Console.WriteLine(" 類型:{0},更改人:{1},更改時間:{2},備註:{3}", attr.RecordType, attr.Author, attr.Date.ToString("yyyy-MM-dd"), attr.Mark); 35 } 36 } 37 Console.WriteLine(); 38 } 39 } 40 } 41 }}
運行效果以下圖所示:
獲取自定義特性的方法二:
首先基於類型(本例中是DemoClass)獲取一個Type對象,而後調用Type對象的GetCustomAttributes()方法,獲取應用於該類型上的特性。
當指定GetCustomAttributes(Type attributeType, bool inherit) 中的第一個參數attributeType時,
將只返回指定類型的特性,不然將返回所有特性;第二個參數指定是否搜索該成員的繼承鏈以查找這些屬性。
代碼以下:
1 namespace ConsoleApp 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 TestAttribute testClass = new TestAttribute(); 8 Type type = testClass.GetType(); 9 object[] records = type.GetCustomAttributes(typeof(RecordAttribute), false); //獲取類型上的特性 10 Console.WriteLine("類型{0}上應用的Record特性:", type.ToString()); 11 Console.WriteLine(); 12 foreach (RecordAttribute record in records) 13 { 14 Console.WriteLine(" 類型:{0},更改人:{1},更改時間:{2},備註:{3}", record.RecordType, record.Author, record.Date.ToString("yyyy-MM-dd"), record.Mark); 15 } 16 Console.WriteLine(); 17 Console.WriteLine("類型{0}的方法上應用的Record特性:", type.ToString()); 18 Console.WriteLine(); 19 foreach (MethodInfo mInfo in type.GetMethods()) //遍歷該類型的全部方法 20 { 21 if (Attribute.IsDefined(mInfo, typeof(RecordAttribute))) //只有在方法上附加了屬性,才遍歷 22 { 23 Console.WriteLine(" 類型{0}的{1}方法上的Record特性", type.ToString(), mInfo.ToString()); 24 Console.WriteLine(); 25 foreach (RecordAttribute record in mInfo.GetCustomAttributes(typeof(RecordAttribute), false)) //遍歷方法上的 特性 26 { 27 Console.WriteLine(" 類型:{0},更改人:{1},更改時間:{2},備註:{3}", record.RecordType, record.Author, record.Date.ToString("yyyy-MM-dd"), record.Mark); 28 } 29 Console.WriteLine(); 30 } 31 } 32 } 33 } 34 }
兩種方法運行的結果是同樣的,如上圖。這兩種方法的區別在與,第一種方法是用的Atrribute基類的靜態方法獲取對應類型的自定義特性的集合。而第二種方案是使用的Type類型的方法獲取的。
demo下載:點擊這裏下載代碼
資料:
http://www.cnblogs.com/JimmyZhang/archive/2008/01/27/1055254.htmlhtml
Attribute在.net編程中的應用(一)
Attribute在.net編程中的應用(二)
Attribute在.net編程中的應用(三)
Attribute在.net編程中的應用(四)
Attribute在.net編程中的應用(五)