C#vs VB.Net,阴影和[重载(不改变参数)]之间的区别是什么

Ahm*_*eed 4 c# vb.net oop overloading shadowing

很抱歉这个问题很长,但我对C#不熟悉(我曾经使用过VB.Net)

我完全理解VB.Net和C#中的重写重载之间的区别.所以覆盖没有问题.

现在,在VB.Net中,Shadowing(使用关键字Shadows)和Overloading(使用带有相同参数的关键字Overloads' )之间存在差异,如下所示:

  • 使用阴影时,它会以相同的名称隐藏每个方法 - 无论参数如何 - 只能成为一个方法(阴影方法).
  • 使用Overloads时 - 使用相同的参数 - 它仅重载(阴影)具有相同名称和参数的方法.

考虑以下代码:

Class A
    Sub MyMethod()
        Console.WriteLine("A.MyMethod")
    End Sub
    Sub MyMethod(ByVal x As Integer)
        Console.WriteLine("A.MyMethod (x)")
    End Sub
    Sub MyMethod2()
        Console.WriteLine("A.MyMethod2")
    End Sub
    Sub MyMethod2(ByVal x As Integer)
        Console.WriteLine("A.MyMethod2 (x)")
    End Sub
End Class

Class B
    Inherits A
    Overloads Sub MyMethod()
        Console.WriteLine("B.MyMethod")
    End Sub
    Shadows Sub MyMethod2()
        Console.WriteLine("B.MyMethod2")
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

然后:

Dim obj As New B()
obj.MyMethod()      'B.MyMethod
obj.MyMethod(10)    'A.MyMethod (x)
obj.MyMethod2()     'B.MyMethod2
Run Code Online (Sandbox Code Playgroud)

而:

obj.MyMethod2(10)   'Error, cuz there's only one 'MyMethod2' (and with zero arguments)
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好..

但是,在C#中,我没有在Shadowing(使用关键字New)和Overloading(相同名称和参数)之间获得相同的区别!

因此,当在C#中尝试相同的代码时(当然使用C#语法:D),以下行:

obj.MyMethod2(10);
Run Code Online (Sandbox Code Playgroud)

将返回>>'A.MyMethod2(x)'

看起来C#中的重载和阴影没什么区别!!

任何人都可以解释为什么存在这种差异?

谢谢

Eri*_*ert 9

这是一个令人困惑的问题.让我把它分解成更小的问题.

什么是继承

当一种类型从另一种类型继承时,基类型的可继承成员也是派生类型的成员.大多数成员都是可继承的; 一些,像建设者,不是.

所有成员?即使是私人的?

是.私人成员是继承的.按名称查找它们可能不合法,但它们仍然是继承的.

在C#中,什么是重载方法?

一种方法是重载当存在名称相同的两种方法,但不同的签名在一个类型.(出于本讨论的目的,方法的签名包括其名称,通用arity,参数数量和参数类型.)

如果我们有一个类型D有两个成员,M(X)和M(Y),它们是重载的,那么其中一个从基类型B继承而另一个在D中声明是完全正常的.仍然是超载.

在C#中,如何解决重载?

这个过程很复杂,但基本规则是:首先汇集给定名称的所有可访问方法的集合.然后删除签名与给定参数不匹配的所有方法.其余方法是适用的方法.

然后识别并保存在最派生类型中声明的方法; 其他适用的方法将被删除.(重写方法被认为是最初声明方法的类型的方法,而不是覆盖它们的类型.)

如果剩下一种方法,那就赢了.否则,评估每对适用的方法,以查看在匹配参数时是否优于另一对; 任何比另一种更糟糕的方法都被淘汰了.如果这个过程产生一种独特的最佳方法,那么它就会赢

还有许多涉及通用方法和破坏者的规则与本讨论无关.

在C#中,方法的名称隐藏了什么?

如果在派生类继承的基类中有方法M(X),派生类可以声明同一签名的另一个成员.该成员隐藏基类中的成员.

特别是,如果隐藏方法是适用的方法,然后重载会选择在隐藏方法的任何基本类型成员,因为我们已经知道,重载丢弃都不在成员最派生类型.由于隐藏方法始终采用比隐藏方法更加派生的类型,因此它总是获胜 - 只要它当然可以访问.

在C#中,我们如何将成员标记为隐藏名称?

你不需要做任何事情; 只需声明该成员隐藏基类成员.但是,C#编译器会警告您隐藏可能是无意的; 它经常是.您可以使用new隐藏成员上的关键字使警告消失.当您打算隐藏成员时,这是最佳做法.

在C#中,如果重载决策无法选择隐藏方法,因为它不适用或无法访问,会发生什么?

然后适用通常的重载决策规则.隐藏方法不适用,因此立即从所考虑的方法集中删除.这可能意味着派生类型中声明的方法不适用,因此基类的成员可能是在派生类型中声明适用方法.

成员阴影如何在VB中工作的规则与C#中的隐藏规则略有不同?

是.

为什么?

C#和VB虽然故意相似,但在同一个演员身上并不是不同的服装.它们是不同的语言,具有不同的历史,不同的设计考虑因素和不同的设计团队.你应该期待像这样的小差异.

那么在C#中隐藏方法和重载方法有什么区别?

两人都宣布成为新成员.添加新重载会添加具有不同签名的方法,并且这些方法可能会也可能不会以相同的类型声明.隐藏方法会添加一个与基本类型中方法的签名完全匹配的新方法.