屬性和中繼資料

來源:互聯網
上載者:User
資料


C#和C++之間一個顯著的區別是它提供了對中繼資料的支援:有關類、對象、方法等其他實體的資料。屬性可以分為二類:一類以CLR的一部分的形式出現,另一種是我們自己建立的屬性,CLR屬性用來支援序列化、排列和COM協同性等。一些屬性是針對一個組合體的,有些屬性則是針對類或介面,它們也被稱作是屬性目標。

將屬性放在屬性目標前的方括弧內,屬性就可以作用於它們的屬性目標。

[assembly:AssemblyDelaySign(false)]
[assembly:AssemblyKeyFile(".\\keyFile.snk")]

或用逗號將各個屬性分開:

[assembly:AssemblyDelaySign(false),
assembly:AssemblyKeyFile(".\\keyFile.snk")]

自訂的屬性

我們可以任意建立自訂屬性,並在認為合適的時候使用它們。假設我們需要跟蹤bug的修複情況,就需要建立一個包含bug的資料庫,但需要將bug報告與專門的修正情況綁定在一塊兒,則可能在代碼中添加如下所示的注釋:

//Bug323fixedbyJesseLiberty1/1/2005.

這樣,在原始碼中就可以一目瞭然地瞭解bug的修正情況,但如果如果把相關的資料儲存在資料庫中可能會更好,這樣就更方便我們的查詢工作了。如果所有的bug報告都使用相同的文法那就更好了,但這時我們就需要一個定製的屬性了。我們可能使用下面的內容代替代碼中的注釋:

[BugFix(323,"JesseLiberty","1/1/2005")Comment="Offbyoneerror"]

與C#中的其他元素一樣,屬性也是類。定製化的屬性類需要繼承System.Attribute:

publicclassBugFixAttribute:System.Attribute

我們需要讓編譯器知道這個屬性可以跟什麼類型的元素,我們可以通過如下的方式來指定該類型的元素:

[AttributeUsage(AttributeTargets.ClassMembers,AllowMultiple=true)]

AttributeUsage是一個作用於屬性的屬性━━元屬性,它提供的是中繼資料的中繼資料,也即有關中繼資料的資料。在這種情況下,我們需要傳遞二個參數,第一個是目標(在本例中是類成員。),第二個是表示一個給定的元素是否可以接受多於一個屬性的標記。AllowMultiple的值被設定為true,意味著類成員可以有多於一個BugFixAttribute屬性。如果要聯合二個屬性目標,可以使用OR操作符串連它們。

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface,AllowMultiple=true)]

上面的代碼將使一個屬性隸屬於一個類或一個介面。

新的自訂屬性被命名為BugFixAttribute。命名的規則是在屬性名稱之後添加Attribute。在將屬性指派給一個元素後,編譯器允許我們使用精簡的屬性名稱調用這一屬性。因此,下面的代碼是合法的:

[BugFix(123,"JesseLiberty","01/01/05",Comment="Offbyone")]

編譯器將首先尋找名字為BugFix的屬性,如果沒有發現,則尋找BugFixAttribute。

每個屬性必須至少有一個構造器。屬性可以接受二種類型的參數:環境參數和具名引數。在前面的例子中,bugID、編程人員的名字和日期是環境參數,注釋是具名引數。環境參數被傳遞到構造器中的,而且必須按在構造器中定義的順序傳遞。

publicBugFixAttribute(intbugID,stringprogrammer,stringdate)
{
this.bugID=bugID;
this.programmer=programmer;
this.date=date;
}

Namedparametersareimplementedasproperties.

屬性的使用

為了對屬性進行測試,我們建立一個名字為MyMath的簡單類,並給它添加二個函數,然後給它指定bugfix屬性。

[BugFixAttribute(121,"JesseLiberty","01/03/05")]

[BugFixAttribute(107,"JesseLiberty","01/04/05",
Comment="Fixedoffbyoneerrors")]
publicclassMyMath

這些資料將與中繼資料存放區在一起。下面是完整的原始碼及其輸出:

自訂屬性

usingSystem;
//建立被指派給類成員的自訂屬性
[AttributeUsage(AttributeTargets.Class,
AllowMultiple=true)]
publicclassBugFixAttribute:System.Attribute
{
//位置參數的自訂屬性構造器
publicBugFixAttribute
(intbugID,
stringprogrammer,
stringdate)
{
this.bugID=bugID;
this.programmer=programmer;
this.date=date;
}
publicintBugID
{
get
{
returnbugID;
}
}

//具名引數的屬性
publicstringComment
{
get
{
returncomment;
}
set
{
comment=value;
}
}

publicstringDate
{
get
{
returndate;
}
}

publicstringProgrammer
{
get
{
returnprogrammer;
}
}

//專有成員資料
privateintbugID;
privatestringcomment;
privatestringdate;
privatestringprogrammer;
}

//把屬性指派給類

[BugFixAttribute(121,"JesseLiberty","01/03/05")]
[BugFixAttribute(107,"JesseLiberty","01/04/05",
Comment="Fixedoffbyoneerrors")]
publicclassMyMath
{

publicdoubleDoFunc1(doubleparam1)
{
returnparam1+DoFunc2(param1);
}

publicdoubleDoFunc2(doubleparam1)
{
returnparam1/3;
}

}

publicclassTester
{
publicstaticvoidMain()
{
MyMathmm=newMyMath();
Console.WriteLine("CallingDoFunc(7).Result:{0}",
mm.DoFunc1(7));
}
}

輸出:

CallingDoFunc(7).Result:9.3333333333333339

象我們看到的那樣,屬性對輸出絕對沒有影響,建立屬性也不會影響代碼的效能。到目前為止,讀者也只是在聽我論述有關屬性的問題,使用ILDASM瀏覽中繼資料,就會發現屬性確實是存在的。




相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

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

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