Ahm*_*eed 4 c# vb.net oop overloading shadowing
很抱歉这个问题很长,但我对C#不熟悉(我曾经使用过VB.Net)
我完全理解VB.Net和C#中的重写和重载之间的区别.所以覆盖没有问题.
现在,在VB.Net中,Shadowing(使用关键字Shadows)和Overloading(使用带有相同参数的关键字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#中的重载和阴影没什么区别!!
任何人都可以解释为什么存在这种差异?
谢谢
这是一个令人困惑的问题.让我把它分解成更小的问题.
什么是继承?
当一种类型从另一种类型继承时,基类型的可继承成员也是派生类型的成员.大多数成员都是可继承的; 一些,像建设者,不是.
所有成员?即使是私人的?
是.私人成员是继承的.按名称查找它们可能不合法,但它们仍然是继承的.
在C#中,什么是重载方法?
一种方法是重载当存在名称相同的两种方法,但不同的签名在一个类型.(出于本讨论的目的,方法的签名包括其名称,通用arity,参数数量和参数类型.)
如果我们有一个类型D有两个成员,M(X)和M(Y),它们是重载的,那么其中一个从基类型B继承而另一个在D中声明是完全正常的.仍然是超载.
在C#中,如何解决重载?
这个过程很复杂,但基本规则是:首先汇集给定名称的所有可访问方法的集合.然后删除签名与给定参数不匹配的所有方法.其余方法是适用的方法.
然后识别并保存在最派生类型中声明的方法; 其他适用的方法将被删除.(重写方法被认为是最初声明方法的类型的方法,而不是覆盖它们的类型.)
如果剩下一种方法,那就赢了.否则,评估每对适用的方法,以查看在匹配参数时是否优于另一对; 任何比另一种更糟糕的方法都被淘汰了.如果这个过程产生一种独特的最佳方法,那么它就会赢
还有许多涉及通用方法和破坏者的规则与本讨论无关.
在C#中,方法的名称隐藏了什么?
如果在派生类继承的基类中有方法M(X),派生类可以声明同一签名的另一个成员.该成员隐藏基类中的成员.
特别是,如果隐藏方法是适用的方法,然后重载会选择在隐藏方法的任何基本类型成员,因为我们已经知道,重载丢弃都不在成员最派生类型.由于隐藏方法始终采用比隐藏方法更加派生的类型,因此它总是获胜 - 只要它当然可以访问.
在C#中,我们如何将成员标记为隐藏名称?
你不需要做任何事情; 只需声明该成员隐藏基类成员.但是,C#编译器会警告您隐藏可能是无意的; 它经常是.您可以使用new隐藏成员上的关键字使警告消失.当您打算隐藏成员时,这是最佳做法.
在C#中,如果重载决策无法选择隐藏方法,因为它不适用或无法访问,会发生什么?
然后适用通常的重载决策规则.隐藏方法不适用,因此立即从所考虑的方法集中删除.这可能意味着派生类型中声明的方法不适用,因此基类的成员可能是在派生类型中声明的适用方法.
成员阴影如何在VB中工作的规则与C#中的隐藏规则略有不同?
是.
为什么?
C#和VB虽然故意相似,但在同一个演员身上并不是不同的服装.它们是不同的语言,具有不同的历史,不同的设计考虑因素和不同的设计团队.你应该期待像这样的小差异.
那么在C#中隐藏方法和重载方法有什么区别?
两人都宣布成为新成员.添加新重载会添加具有不同签名的方法,并且这些方法可能会也可能不会以相同的类型声明.隐藏方法会添加一个与基本类型中方法的签名完全匹配的新方法.