.Net下Attribute的特性簡單入門

我相信不少初學者,和我一樣,經常看到以下這樣的代碼

    

對於圖示中紅線標註的東西,通過查閱資料,知道叫Attribute(特性).於是Google、百度一番,似乎說這個話題的博文不少,估計看完了也是雲裏霧裏的。ok...鄙人就冒昧,用最簡單的辦法來嘗試學習下 Attribute.

1、Attribute到底是什麼?

先不要去看那些一大段的文字說明,Attribute翻譯過來:(推薦使用百度的翻譯.不錯...下面的翻譯結果引用自百度詞典)

attribute1

名詞 n. [C]

2.(,,職務等的)標誌,象徵

對,Attribute沒什麼複雜的,有這個標記的,就認爲這個東東(類、字段)是具有某個標誌、象徵。沒什麼複雜的,就如我們在超市購物,商品上有一個條形碼的Attribute.

可能有朋友要問了,比如一個商品,條形碼爲什麼不使用一個屬性來描述?(請參見屬性和Attribute的區別)

這裏結合官方的文檔,用通俗的話說:

  可以通過Attribute將一些額外信息加在一些目標元素上(類,字段,接口等),程序編譯的時候就將這些額外的信息系列化程序集的元數據中,當你運行程序的時候可以通過反射技術從程序集元數據中讀取這些額外信息,並根據這些額外信息決定你程序的行爲

2、屬性和Attribute的區別

先不要考慮那麼多,記錄這個兩個東西沒有必然聯繫。OK..下面,直接用代碼的方式進行學習

3、使用.Net已定義好的Attribute

新建一個控制檯項目Demo,在新建一個MyClass類

MyClass
    public class MyClass
{
[Obsolete("這是一箇舊的方法,請調用新的方法NewMethod")]
public void OldMethod()
{
Console.WriteLine("這是舊方法");
}
[Obsolete("這是一箇舊的方法,請調用新的方法NewMethod",true)]
public void OldMethod1()
{
Console.WriteLine("這是舊方法");
}
public void NewMethod()
{
Console.WriteLine("這是新方法");
}
}

我們在Program中編寫調用MyClass類的代碼

調用MyClass
        MyClass myclass = new MyClass();
myclass.OldMethod();
myclass.OldMethod1();
Console.ReadKey();

此時,我們編譯Demo這個項目,會發現有警告和錯誤

是不是很神奇,爲什麼在方法上使用Obsolete這樣的定製特性,編譯器能夠做出相應處理,如在使用標記了Obsolete特性的方法時會發出警告信息,但如果我們自己定製的Attribute時,編譯器會做什麼處理呢?

4、自定義Attribute

1、先註釋掉Program調用MyClass類的測試代碼.新建一個類MyFirstAttribute.(這裏的類名一定是xxxAttribute,原因:)

定義的Attribute必須直接或間接從公共抽象類System.Attribute派生。所以我們前面Obsolete、STAThread和Serializable都是派生於Attribute。

自定義Attribute的命名規範,其規則是“特性名+Attribute”。

MyFirstAttribute
    class MyFirstAttribute:Attribute
{
public string Msg { get; set; }
public MyFirstAttribute(string msg)
{
Msg = msg;
}
}

在Demo項目中新增一個類Person,使用我們自定義的的MyFirstAttribute類能夠應用在這個類上

Person
  [MyFirstAttribute("自定義第一個Attribute")]
class Person
{
}

我們給Person類使用了自定義的MyFirstAttribute標記後,程序應該怎樣獲取到Person的MyFirstAttribute內容呢?在Program類中編寫測試代碼

獲取自定義的GetCustomAttributes
         var attributes = typeof(Person).GetCustomAttributes(typeof(MyFirstAttribute), true);
MyFirstAttribute myAttribute = attributes[0] as MyFirstAttribute;
if (myAttribute != null)
{
Console.WriteLine(myAttribute.Msg);
}

編譯且運行Demo項目,程序運行結果

到這裏,我們就自定義了一個MyFirstAttribute,並且成功的調用測試了.回頭看下這簡單的代碼,會發現一個模型,就是我們自定義了一個Attribute類,當應用於目標元素上(類,字段,接口等),我們在寫程序去獲取(反射)目標元素時,解析我們的Attribute類,再實現Attribute的功能代碼.

比如,我想實現這樣的效果:我們給Person類中的屬性打上一個自定義的標記,在使用了自定義的標記屬性,在將Person對象寫到文件的時候,打了自定義標記的,就保存到文件.否則就不保存.

Ok.先定義一個Attribute(注意:命名規則和繼承關係)

View Code
    class WriteFileAttribute:Attribute
{
}

在Person類中,新增幾個屬性代碼,並使用標記

Person
    class Person
{
[WriteFile]
public int Id { get; set; }
[WriteFile]
public string Name { get; set; }
/// <summary>
/// 密碼,不使用標記
/// </summary>
public string Pwd { get; set; }
[WriteFile]
public int Age { get;set;}
}

 然後我們Program中編寫調用Person類的代碼

WriteFileAttribute
         Person per1 = new Person() { Age = 20, Id = 1, Name = "Winloa", Pwd = "123" };
StringBuilder content = new StringBuilder();
//分析Person中那些屬性使用了WriteFileAttribute,如果使用了,就將此屬性值寫入到文件
Type typePerson = per1.GetType();
PropertyInfo [] propArry= typePerson.GetProperties();
foreach (var item in propArry)
{

object [] obj=item.GetCustomAttributes(typeof(WriteFileAttribute), false);
if (obj.Length > 0)
{
//說明該屬性使用了WriteFileAttribute標記
content.Append(item.Name + "\t" + item.GetValue(per1, null)+"\r\n");
}
}
File.WriteAllText("D:\\Attribute.txt", content.ToString());

然後我們編譯Demo項目並且運行.我們發現在D盤根目錄下有一個Attribute.txt文件

Person類中的Pwd屬性並沒有使用WriteFileAttribute,所以在保存到文件時,沒有記錄下來。

5、總結

Attribute通俗的說,就是一個標記,這些標記有.net系統提供的,我們也可以自定義,自定義的Attribute類,應該注意:命名規則和繼承關係

然後我們使用了自定義的Attribute類,應該有響應的解析類,要不然自定義的Attribute程序也不知道如何調用

比如我們想把前面的Person類的對象持久化到數據庫(這裏需要考慮主鍵、數據庫兼容等情況)

1、自定義一個Attribute--->WriteDataBaseAttribute.cs

2、在Person中使用WriteDataBaseAttribute

3、寫一個解析WriteDataBaseAttribute類,在WriteDataBaseAttribute中完成對數據庫的CRUD


筆者測試:這篇文章寫的很好,值得細讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章