Dot-Net
VB.NET 中的陰影與重載
當我們
new在 C# 中時,我個人認為這只是一種解決方法來覆蓋沒有虛擬/可覆蓋聲明的屬性,在 VB.NET 中我們有兩個“概念”Shadows和Overloads.在哪種情況下更喜歡一個?
存在三個密切相關的概念;覆蓋,陰影和重載。
覆蓋是當您為虛擬方法創建新實現時。
陰影是當您為方法創建新的非虛擬實現時。
重載是當您添加具有相同名稱但不同參數的方法時。
這三個概念在 C# 和 VB 中都可用。
實際上,我已經通過使用
ShadowsvsOverloads為基類中具有相同名稱和簽名的方法編譯相同的程式碼並查看ildasm兩者的輸出來確認。唯一的區別是Overloads大小寫指定hidebysig。Jon Skeet 在這個答案中最好地解釋了這一點的重要性。
但簡單地說,這意味著只有基類具有被重新定義的方法的重載時才會有真正的區別:
Shadows將導致所有這些重載都無法通過派生類呼叫,其中Overloads只替換一種方法。請注意,這只是一種語言結構,並非由 CLI 強制執行(即 C# 和 VB.NET 強制執行此操作,但其他語言可能不會)。
一個簡單的程式碼範例:
Module Module1 Sub Main() Dim a1 As C1 = New C2 Dim a2 As New C2 a1.M1() a2.M1() a1.M2() a2.M2() a1.M3() a2.M3() a1.M1(1) ' Overloads on M1() allows the M1(int) to be inherited/called. a2.M1(1) a1.M2(1) ' Shadows on M2() does not allow M2(int) to be called. 'a2.M2(1) a1.M3(1) ' Shadows on M3() does not allow M3(int) to be called, even though it is Overridable. 'a2.M3(1) If Debugger.IsAttached Then _ Console.ReadLine() End Sub End Module Class C1 Public Sub M1() Console.WriteLine("C1.M1") End Sub Public Sub M1(ByVal i As Integer) Console.WriteLine("C1.M1(int)") End Sub Public Sub M2() Console.WriteLine("C1.M2") End Sub Public Sub M2(ByVal i As Integer) Console.WriteLine("C1.M2(int)") End Sub Public Overridable Sub M3() Console.WriteLine("C1.M3") End Sub Public Overridable Sub M3(ByVal i As Integer) Console.WriteLine("C1.M3(int)") End Sub End Class Class C2 Inherits C1 Public Overloads Sub M1() Console.WriteLine("C2.M1") End Sub Public Shadows Sub M2() Console.WriteLine("C2.M2") End Sub Public Shadows Sub M3() Console.WriteLine("C2.M3") End Sub ' At compile time the different errors below show the variation. ' (Note these errors are the same irrespective of the ordering of the C2 methods.) ' Error: 'Public Overrides Sub M1(i As Integer)' cannot override 'Public Sub M1(i As Integer)' because it is not declared 'Overridable'. 'Public Overrides Sub M1(ByVal i As Integer) ' Console.WriteLine("C2.M1(int)") 'End Sub ' Errors: sub 'M3' cannot be declared 'Overrides' because it does not override a sub in a base class. ' sub 'M3' must be declared 'Shadows' because another member with this name is declared 'Shadows'. 'Public Overrides Sub M3(ByVal i As Integer) ' Console.WriteLine("C2.M3(int)") 'End Sub End Class上面的輸出:
C1.M1 C2.M1 C1.M2 C2.M2 C1.M3 C2.M3 C1.M1(int) C1.M1(int) C1.M2(int) C1.M3(int)輸出顯示
Shadows呼叫在直接呼叫時使用,C2而不是在通過 間接呼叫時使用C1。