簡(jiǎn)單概括VB.NET默認(rèn)屬性
在向大家詳細(xì)介紹VB.NET默認(rèn)屬性之前,首先讓大家了解下TextBox的默認(rèn)屬性是Text,然后全面介紹VB.NET默認(rèn)屬性。在原先的VB6里,有一項(xiàng)奇特的功能——默認(rèn)屬性。在VB6中,對(duì)象的名稱可以直接表示該對(duì)象的默認(rèn)屬性。比如TextBox的默認(rèn)屬性是Text,所以下面的代碼
- Text1.Text = "Hello"
就可以簡(jiǎn)化為
- Text1 = "Hello"
這種簡(jiǎn)化給VB帶來了很多麻煩,賦值運(yùn)算就需要兩個(gè)關(guān)鍵字——Let和Set,結(jié)果屬性過程也需要Let和Set兩種。而且這種特征在后期綁定的時(shí)候仍能工作。到了VB.NET,這項(xiàng)功能被大大限制了,現(xiàn)在只有帶參數(shù)的屬性才可以作為默認(rèn)屬性。如
- List1.Item(0) = "Hello"
可以簡(jiǎn)化為
- List1(0) = "Hello"
這種語法讓有默認(rèn)屬性的對(duì)象看起來像是一個(gè)數(shù)組。那么VB怎么判斷一個(gè)屬性是否是默認(rèn)屬性呢?看下列代碼
- Public Class PropTest
- Public Property P1(ByVal index As Integer) As String
- Get
- End Get
- Set(ByVal Value As String)
- End Set
- End Property
- Default Public Property P2(ByVal index As Integer) As String
- Get
- End Get
- Set(ByVal Value As String)
- End Set
- End Property
- End Class
P1和P2兩個(gè)屬性基本上完全相同,***的不同是P2帶有一個(gè)Default修飾符。反匯編這個(gè)類以后,可以發(fā)現(xiàn)兩個(gè)屬性完全相同,沒有任何差異。但是PropTest類卻被增加了一個(gè)自定義元屬性System.Reflection.DefaultMemberAttribute。這個(gè)元屬性指定的成員是InvokeMember所使用默認(rèn)類型,也就是說后期綁定也可以使用默認(rèn)屬性??墒俏以囼?yàn)將DefaultMember元屬性手工添加到類型上卻不能達(dá)到讓某屬性成為默認(rèn)屬性的功能??磥磉@項(xiàng)功能又是VB的一項(xiàng)“語法甜頭”。但是,VB或C#的編譯器對(duì)別人生成的類的默認(rèn)屬性應(yīng)該只能通過 DefaultMemberAttribute來判斷,所以我將一個(gè)VB類只用DefaultMemberAttribute指定一個(gè)默認(rèn)方法,不使用 Default,然后將它編譯以后給C#用,果然,C#將它識(shí)別為一個(gè)索引器(indexer)!
既然說到了C#的索引器,我們就順便來研究一下VB和C#屬性方面的不同。剛才的實(shí)驗(yàn)結(jié)果是VB.NET默認(rèn)屬性在C#中就是索引器。但是VB仍然可以用屬性的語法來訪問默認(rèn)屬性,而C#只能用數(shù)組的語法訪問索引器。更特別的是,VB可以創(chuàng)建不是默認(rèn)屬性,但是帶有參數(shù)的屬性,如上面例子里的P1,而C# 則不支持帶參數(shù)的屬性,如果將VB編寫的,含有帶參數(shù)屬性的類給C#用,C#會(huì)提示“屬性不受該語言支持,請(qǐng)用get_XXX和set_XXX的語法訪問”。也就是說,帶參數(shù)的屬性是CLR的一項(xiàng)功能,但不符合CLS(通用語言規(guī)范),因此就會(huì)出現(xiàn)跨語言的障礙。這也更加深了我們對(duì)CLS的認(rèn)識(shí)——如果你希望讓你的代碼跨語言工作,請(qǐng)一定要注意符合CLS。
【編輯推薦】