VB.NET中的阴影与重载

ser*_*hio 22 .net vb.net oop overloading shadows

当我们使用newC#时,我个人认为只是作为一种解决方法来覆盖没有虚拟/可覆盖声明的属性,在VB.NET中我们有两个"概念" ShadowsOverloads.

在哪种情况下喜欢彼此?

Mar*_*urd 18

我实际上通过使用Shadowsvs 编译相同的代码来确认Overloads基类中具有相同名称和签名的方法,并查看ildasm两者的输出.唯一的区别是Overloads案例规定hidebysig.

Jon Skeet在这个答案中最好地解释了这一点的重要性.

但简单地说,如果基类具有重新定义的方法的重载,则意味着只有真正的区别:

  • Shadows将导致所有这些重载通过派生类不可调用,其中as
  • 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
Run Code Online (Sandbox Code Playgroud)

以上输出:

C1.M1
C2.M1
C1.M2
C2.M2
C1.M3
C2.M3
C1.M1(int)
C1.M1(int)
C1.M2(int)
C1.M3(int)
Run Code Online (Sandbox Code Playgroud)

输出显示直接Shadows调用时使用C2的调用,而不是间接调用时调用C1.


Guf*_*ffa 14

有三个密切相关的概念; 覆盖,阴影和重载.

覆盖是为虚拟方法创建新实现时.

阴影是指为方法创建新的非虚拟实现.

重载是指添加具有相同名称但参数不同的方法.

C#和VB都提供了这三个概念.

  • 问题不在于覆盖,这没关系。现在,**重载**还可用于**隐藏**基类中的现有成员或重载成员集。当您以这种方式使用重载时,您可以声明与基类成员具有相同名称和相同参数列表的属性或方法,并且不提供 Shadows 关键字。我看到 *new* (C#) = *Shadows* (VB.NET),C# 中相当于重载的是什么? (2认同)