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