C#基礎--Attribute(標籤) 和 reflect(反射) 應用

來源:互聯網
上載者:User

標籤:eric   儲存   new   應用程式   obj   reg   return   if語句   tip   

1.Attribute的定義與作用: 通用語言執行平台允許你添加類似關鍵字的描述聲明,叫做attributes, 它對程式中的元素進行標註,如類型、欄位、方法和屬性等。Attributes和Microsoft .NET Framework檔案的中繼資料儲存在一起,可以用來向運行時描述你的代碼,或者在程式啟動並執行時候影響應用程式的行為.比如在WCF中常用的序列化。比如添加的[DataMenber]就是一種標籤。以及xml序列化也是一樣的。 2.Reflect的定義與作用 反射可以用於觀察並修改程式在運行時的執行。一個reflection-oriented程式組件可以監測一個範圍內的代碼執行情況,可以根據期望的目標與此相關的範圍修改本身。這通常是通過在運行時動態分配程式碼實現。在物件導向的程式設計語言如Java中,反射允許在編譯期間不知道介面的名稱,欄位、方法的情況下在運行時檢查類、介面、欄位和方法。它還允許的執行個體化新對象和調用的方法。(摘抄至維基百科). 其實可以簡單理解為,通過反射可以很輕易的擷取到一個類中的所有方法屬性欄位狀態。 3.為了更方便的認識反射以及Attribute的應用,下面有個例子. 業務背景如下: 有個Person對象,目前只有Name和Num屬性,然後要用方法校正Person對象的合法性。 判斷規則: 1.Name必填,若Name為空白,則提示"Name不可為空"; 2.Num可以為空白,但是若有資料的話必須由數字組成,若為非數字字串則彈出"格式不正確".         3.Address可以為空白,若有資料的話長度不能超過12,若超過12則提示"Address 長度不能超過12" 需要考慮: 對於Person類,以後熟悉的判斷規則可能會變化,也可能增加屬性,減少屬性。 4.解決方案一: 對於常規解決方案,可能大家會想到。目前只有Name,Address,Num三個屬性,每次我就寫三個程式碼片段分別對Name,Address,Num驗證。如果增加屬性, 比如增加了公用屬性EmailAddress,那麼就必須添加驗證字串是否是郵箱的代碼,若刪除了某個屬性,就吧判斷該屬性是否合格的代碼刪除掉不進行判斷。這個也是我最開始想到的方法。不過這樣不好的地方是可維護性不好。改動太大了。而且會導致重複代碼。不如如果需求改成Address不可為空了。那麼在判斷address是否合法的時候還要去添加判斷不可為空的情況。 5.解決方案二: 為瞭解決方案一的問題,其實我們可以通過Attribute和反射來實現。思路如下: 5.1 首先我們建立一個PersonCheckAttribute對象,他繼承與System.Attribute. 複製代碼using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace ReflectTest.Model{ public class PersonCheckAttribute:Attribute { // 三個bool變數用於確定是有要驗證這些資訊 private bool checkEmpty = false; //是否為空白 private bool checkMaxLength = false; //最大長度 private bool checkRegex = false; //用Regex驗證參數(是郵箱,是否刷數字) private int maxLength = 0; private string regexStr = string.Empty; public bool CheckEmpty { get { return this.checkEmpty; } set { this.checkEmpty = value; } } public bool CheckMaxLength { get { return this.checkMaxLength; } set { this.checkMaxLength = value; } } public bool CheckRegex { get { return this.checkRegex; } set { this.checkRegex = value; } } public int MaxLength { get { return this.maxLength; } set { this.maxLength = value; } } public string RegexStr { get { return this.regexStr; } set { this.regexStr = value; } } }}複製代碼 5.2 然後我們來添加Person類。注意裡面的標籤。 Tips:我在裡面打了標籤,對於5.1的PersonCheckAttribute類中bool變數用來確定是否要進行驗證,公用屬性用來存取判斷參數。   複製代碼using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; namespace ReflectTest.Model{ public class Person { [PersonCheck(CheckEmpty=true)] public string Name { get; set; } [PersonCheck(CheckRegex = true, RegexStr = "^[0-9]*[1-9][0-9]*$")] public string Num { get; set; } [PersonCheck(CheckMaxLength = true, MaxLength = 12)] public string Address { get; set; } }}複製代碼 5.3 屬性已經搞定,下面來看看,如何通過反射來擷取類的公用屬性,以及每個屬性的Attribute。 複製代碼using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using ReflectTest.Model;using System.Reflection;using System.Text.RegularExpressions; namespace ReflectTest.Business{ public class PersonCheck { // 擷取所有的錯誤提示 public static string GetErrorMessage(Person person) { PropertyInfo[] propertyInfos = person.GetType().GetProperties(); // 擷取一個類的所有屬性 string errorMsg = string.Empty; //對所有公用屬性(Name,Num,Address)遍曆 foreach (PropertyInfo info in propertyInfos) { errorMsg += GetSignalPropertity(info, person); } return errorMsg; } // 擷取單個公用屬性的Attribute.也就是model類裡面的[PersonCheck]資訊 private static string GetSignalPropertity(PropertyInfo propertyInfo,Person person) { // 因為對於此樣本,每個Properties(屬性)只有一個Attribute(標籤),所以用了first()來擷取, // 不過有一點,就是必須在屬性裡面添加[PersonCheck]標籤,但是可以不設定表情裡面的欄位.因為沒有的.GetCustomAttributes()返回為null.指向first會報錯. PersonCheckAttribute attribute = propertyInfo.GetCustomAttributes().First() as PersonCheckAttribute; string errorMsg = string.Empty; //以下的if語句是判斷標籤裡面的設定,設定了什麼就執行什麼資料校正 if (attribute.CheckEmpty) { string obj = propertyInfo.GetValue(person) as string; if (string.IsNullOrEmpty(obj)) { errorMsg += Environment.NewLine + string.Format("{0} 不可為空", propertyInfo.Name); } } if (attribute.CheckMaxLength) { string obj = propertyInfo.GetValue(person) as string; if (obj != null && obj.Length > attribute.MaxLength) { errorMsg += Environment.NewLine + string.Format("{0} 最大長度為{1}", propertyInfo.Name, attribute.MaxLength); } } // 對於判斷數字郵箱都可以通過Regex if (attribute.CheckRegex) { string obj = propertyInfo.GetValue(person) as string; Regex regex = new Regex(attribute.RegexStr); if (obj != null && !regex.IsMatch(obj)) { errorMsg += Environment.NewLine + string.Format("{0} 格式不對", propertyInfo.Name); } } return errorMsg; } }}

C#基礎--Attribute(標籤) 和 reflect(反射) 應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.