VB.NET類型提升失效問題總結(jié)
VB.NET是一款運(yùn)行機(jī)制和Java類似的編程語(yǔ)言。其具有面向?qū)ο筇匦?,能夠支持代碼托管,而且界面簡(jiǎn)單,結(jié)構(gòu)穩(wěn)定,為開發(fā)人員帶來了極大的好處。在這里我們會(huì)通過對(duì)VB.NET類型提升的一些相關(guān)問題的解疑,來對(duì)這門語(yǔ)言進(jìn)行深入的研究。
在模塊中聲明編程元素時(shí),VB.NET會(huì)將其范圍提升到包含該模塊的命名空間。這稱為VB.NET類型提升。
下面的示例演示某個(gè)模塊和該模塊的兩個(gè)成員的主干定義。
- Namespace projNamespace
- Module projModule
- Public Enum basicEnum As Integer
- one = 1
- two = 2
- End Enum
- Public Class innerClass
- Public Sub numberSub(ByVal firstArg As Integer)
- End Sub
- End Class
- End Module
- End Namespace
在 projModule 中的模塊級(jí)別上聲明的編程元素將被提升到 projNamespace。在前面的示例中,提升了 basicEnum 和 innerClass,但是沒有提升 numberSub,因?yàn)樗皇窃谀K級(jí)別上聲明的。
VB.NET類型提升的結(jié)果
類型提升的結(jié)果是一個(gè)限定字符串不需要包括模塊名稱。下面的示例對(duì)前面示例中的過程發(fā)出兩個(gè)調(diào)用。
- Sub usePromotion()
- projNamespace.projModule.innerClass.numberSub
(projNamespace.projModule.basicEnum.one)- projNamespace.innerClass.numberSub(projNamespace.basicEnum.two)
- End Sub
在前面的示例中,***個(gè)調(diào)用使用完全限定字符串。但由于進(jìn)行了類型提升,因此這不是必需的。第二個(gè)調(diào)用也訪問模塊的成員,但在限定字符串中不包括 projModule。
VB.NET類型提升的失效
如果命名空間中的成員與某個(gè)模塊成員同名,則對(duì)該模塊成員的類型提升將會(huì)失效。下面的示例演示同一命名空間中枚舉和模塊的主干定義。
- Namespace thisNamespace
- Public Enum abc
- first = 1
- second
- End Enum
- Module thisModule
- Public Class abc
- Public Sub abcSub()
- End Sub
- End Class
- Public Class xyz
- Public Sub xyzSub()
- End Sub
- End Class
- End Module
- End Namespace
在前面的示例中,Visual Basic 無法將類 abc 提升到 thisNameSpace,因?yàn)樵诿臻g級(jí)別上已存在同名的枚舉。若要訪問 abcSub,必須使用完全限定字符串 thisNamespace.thisModule.abc.abcSub。但是,仍會(huì)提升 xyz 類,您可以使用較短的限定字符串 thisNamespace.xyz.xyzSub 來訪問 xyzSub。
分部VB.NET類型提升的失效
如果模塊內(nèi)的類或結(jié)構(gòu)使用分部 (Visual Basic) 關(guān)鍵字,則對(duì)該類或結(jié)構(gòu)的類型提升會(huì)自動(dòng)失效,無論命名空間是否具有同名的成員。模塊中的其他元素仍然符合類型提升的條件。
結(jié)果。 分部定義的類型提升失效可能導(dǎo)致意外的結(jié)果,甚至導(dǎo)致編譯器錯(cuò)誤。下面的示例演示類的主干分部定義,其中一個(gè)定義位于模塊內(nèi)。
- Namespace sampleNamespace
- Public Partial Class sampleClass
- Public Sub sub1()
- End Sub
- End Class
- Module sampleModule
- Public Partial Class sampleClass
- Public Sub sub2()
- End Sub
- End Class
- End Module
- End Namespace
在前面的示例中,開發(fā)人員可能期望編譯器合并 sampleClass 的兩個(gè)分部定義。但是,編譯器不考慮 sampleModule 內(nèi)分部定義的提升。因此,它嘗試編譯兩個(gè)名稱均為 sampleClass 但具有不同限定路徑的不同類。#t#
只有在兩個(gè)分部定義的完全限定路徑相同時(shí),編譯器才會(huì)對(duì)這兩個(gè)分部定義進(jìn)行合并。
建議
下面的建議提供了良好的編程做法。
***名稱。 當(dāng)您可以完全控制編程元素的命名時(shí),在所有位置使用***名稱始終是一個(gè)好辦法。相同的名稱需要額外的限定,并可能使代碼難以閱讀,還可能導(dǎo)致難以發(fā)現(xiàn)的錯(cuò)誤和意外的結(jié)果。
完全限定。 當(dāng)您在同一命名空間中使用模塊和其他元素時(shí),最安全的方法是對(duì)所有編程元素始終使用完全限定。如果某個(gè)模塊成員的VB.NET類型提升失效,而您沒有完全限定該成員,則無意中可能會(huì)訪問另一個(gè)編程元素。