C# 中特性(Attribute)的使用簡介

來源:互聯網
上載者:User

Attribute(特性)
MSDN給出的定義:
  Attribute 類將預定義的系統資訊或使用者定義的自訂資訊與目標元素相關聯。目標元素可以是程式集、類、建構函式、委託、枚舉、事件、欄位、介面、方法、可攜式執行檔模組、參數、屬性 (Property)、傳回值、結構或其他特性(Attribute)。
在.Net程式中,可以使用特性(Attribute)來解決許多問題。如:將WebService中介面函數標記為WebMethod,將類標記為可序列化等等。

  此外,我們也可以自訂Attribute,來實現我們需要的功能。但自訂Attribute必須繼承自Attribute類。Attribute中有很多方法或者屬性,為我們提供了強大的功能。一般我們通過反射的方式來使用Attribute。

下面結合實際項目中的使用談談自己的體會。
需求:項目中有一個專門的日誌庫。現在項目中需要前端用到查詢、翻頁、按各個欄位排序等等功能。由於日誌資料可能有無效的資料,並且資料量較大。為了提升統計、翻頁效能,所以建立了許多暫存資料表。如果在實際操作中為一個一個不同的需求去建立暫存資料表,造成代碼大量重複臃腫,並且不便於統一管理,考慮到的方案是通過Attribute的方式,統一建暫存資料表。
主體思路如下:通過自訂特性來描述要建立暫存資料表的欄位的相互關聯類型、長度等等資訊,然後通過反射的方式擷取這些欄位對應的這些特性,然後構造相應的SQL命令就可以完成暫存資料表的建立了。
特性定義如下:

[AttributeUsage(AttributeTargets.Property)]public class TableFieldAttribute : Attribute{/// <summary>/// 欄位長度/// </summary>public int Length { get; set; }/// <summary>/// 欄位描述/// </summary>public string Describe { get; set; }/// <summary>/// 欄位類型/// </summary>public string Type { get; set; }}

  

以上AttributeUsage,也是一個繼承自Attribute的類,他的作用就是標誌自訂類的使用範圍,如:欄位,屬性,類,方法。以及使用我們自訂類
標記的類的子類是否繼承特性等。
有了這個自訂特性,將它運用到實體上就行了。

public class TableEntity{[TableField(Describe = "Guid主鍵", Length = 36, Type = "uniqueidentifier")]public Guid Guid { get; set; }[TableField(Describe = "名稱", Length = 36, Type = "varchar ")]public string Name { get; set; }}

  

這樣在實體定義上,我們就已經有了定義好了資料類型,長度等等。在實際要建暫存資料表時,通過反射要建暫存資料表的實體,便能構造相應的SQL命令了。

工具類的定義:public class Tools<T> where T : class。實際使用時,將泛型型別換成相應的類型即可。
主要給出如何使用反射來擷取暫存資料表具體欄位的資訊代碼:

public static List<Record> GetTableFieldsInformation(){Type t = typeof(T);PropertyInfo[] propertyInfos = t.GetProperties();List<Record> tableEntities = new List<Record>();propertyInfos.ToList().ForEach(property =>{IList<CustomAttributeData> list = property.GetCustomAttributesData();if (list.Count == 1){tableEntities.Add(GetTableEntity(list[0].NamedArguments, property));}else{throw new Exception();}});return tableEntities;}

  

這樣, GetTableFieldsInformation()方法中返回的List就是包含了暫存資料表一個欄位的所有資訊的列表。我們迴圈列表,構造Sql命令
主要代碼如下:

recordEntities.ForEach(record =>{if (i == 0){sql = "CREATE TABLE [" + record.TableName + "](";}if (list.All(item => !record.Type.Equals(item, StringComparison.OrdinalIgnoreCase))){sql += string.Format("{0} {1}({2}),", record.FieldName, record.Type, record.Length);}else{sql += string.Format("{0} {1},", record.FieldName, record.Type);}i++;});

  

程式最終執行後如:

主要的思想就是這些。另外,如果你細心,你會發現AttributeUsage特性使用和我定義的TableFieldAttribute使用方式上有寫不一樣。
TableFieldAttribute的使用方式:[TableField(Describe = "Guid主鍵", Length = 36, Type = "uniqueidentifier")]
AttributeUsage的使用方式:[AttributeUsage(AttributeTargets.Property)]。
同樣是自訂的特性,為什麼我們定義的和Framework庫裡的使用不一樣呢。?通過Reflect看看AttributeUsage的源碼,如:

標記的地方來看,是由於在AttributeUsage中屬性的定義【 AttributeTargets ValidOn】以及建構函式的定義不一樣導致的。
有興趣深入研究的同學可以自己試試。

後記:特性的使用是很強大的一項功能。本例中使用的僅僅是其他很小的一部分。因此只對在實際應用中做了寫說明。另:代碼是沒有經過細緻整理

代碼下載:http://files.cnblogs.com/tyb1222/Attributes.rar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.