C#中的方法隐藏和阴影有什么区别?

C#中的方法隐藏和阴影有什么区别?,c#,polymorphism,shadowing,method-hiding,C#,Polymorphism,Shadowing,Method Hiding,C#中的方法隐藏和阴影有什么区别?它们是相同的还是不同的?我们可以称之为多态性(编译时或运行时)吗?这两个术语在C#中的意思相同 方法隐藏==阴影 当您不希望基类方法在继承类中可见/可用时,可以将其用作多态性的一种形式 阴影方法与基类完全解耦-这是一种新方法。之所以使用“隐藏”一词,是因为它与基类中的一个具有相同的签名,并且“隐藏”了它——它打破了继承链。它们只是同一事物的两个不同的词,但在您最常使用它们的上下文中有所不同。通常,所谓的“隐藏”与多态性有关,而所谓的“阴影”则与多态性无关 用C#

C#中的方法隐藏和阴影有什么区别?它们是相同的还是不同的?我们可以称之为多态性(编译时或运行时)吗?

这两个术语在C#中的意思相同

方法隐藏==阴影

当您不希望基类方法在继承类中可见/可用时,可以将其用作多态性的一种形式


阴影方法与基类完全解耦-这是一种新方法。之所以使用“隐藏”一词,是因为它与基类中的一个具有相同的签名,并且“隐藏”了它——它打破了继承链。

它们只是同一事物的两个不同的词,但在您最常使用它们的上下文中有所不同。通常,所谓的“隐藏”与多态性有关,而所谓的“阴影”则与多态性无关

用C#的说法,当你说“隐藏”时,你通常谈论的是继承,其中一个更派生的方法从普通的继承方法调用链中“隐藏”一个基类方法

当你说“shadow”时,你通常指的是作用域:内部作用域中的标识符是更高作用域中的标识符的“shadow”。在其他语言中,C#中所谓的“隐藏”有时也被称为“阴影”

两者都是编译时概念;它们描述了编译器绑定给定标识符时,给定标识符在给定上下文中引用的对象

public class A
{
  public int B;
  public void C()
  {
    return this.B;
  }
}

public class D : A
{
  public int X;

  public new void C()
  {
    var X = 1.0m;
    return X;
  }
}
方法
D.C()
“隐藏”方法
A.C()
;通常,对
D.C()
的调用总是会调用基类
a.C()
方法,因为它不是
virtual
。我们不希望这样;我们想要
D.C()
。很明显,这是你应该避免的,因为这很让人困惑,特别是当你开始把你的D变成A的时候,但是如果你需要它,它是存在的。另外,请注意方法隐藏是自动的:如果这里没有
new
关键字,
D.C()
仍然隐藏
A.C()
,但是我们会收到一个警告,因为通常这不是您想要的。
new
关键字清楚地表明,这才是我们真正想要的

局部变量
D.C()
中的
X
仅在
D.C()
的范围内隐藏类成员
D.X
。在本例中,范围中有两个东西可以合法地称为
X
,编译器需要规则来告诉它您指的是哪一个。“本地性更强”的
X
会对“本地性较弱”的
D.X
进行阴影处理,这就是我们得到的结果。

在VB.NET()中,C#()的名称隐藏被称为阴影处理


只有在重写是一种“多态性”(即静态或编译时)的意义上,才可以将其视为多态性。它不是调用虚函数的经典意义上的多态性。

VB.NET编译器将其称为隐藏,在C中称为隐藏。在C#中称之为阴影是VB的一种溢出

这是一个编译器警告,本质上是基类和派生类之间的名称冲突

我们可以称它们为多态性(编译时或运行时)吗

它当然不是运行时多态性的一种形式。对隐藏或隐藏方法的调用在编译时解析。这使得它通常不会被称为或被认为是多态性

C#中的方法隐藏和阴影有什么区别

阴影是另一个常用的隐藏术语。C#规范只使用“隐藏”,但两者都可以接受

您只调用了“方法隐藏”,但除了方法隐藏之外,还有其他隐藏形式。例如:

namespace N
{   
    class D {}
    class C 
    {
        class N
        {
            class D
            {
                 N.D nd; // Which N.D does this refer to?
嵌套类N在D中时隐藏名称空间N

我们可以称它们为多态性(编译时或运行时)吗


方法隐藏可以用于多态性,是的。您甚至可以将方法隐藏与方法重写混合使用;通过隐藏旧的虚拟方法来引入新的虚拟方法是合法的;在这种情况下,选择哪个虚拟方法取决于接收器的编译时和运行时类型。这样做会让人非常困惑,如果可能的话,您应该避免这样做。

不,这是一个不同的比较。为了进一步澄清,这种类型的方法调用是在编译时确定的(静态绑定)。如果需要运行时求值或动态绑定,则必须在子类中使用
virtual
(和
override
)。我认为编译时评估根本不是多态代码,但我确信其他人有不同的观点。@Matthew-
virtual
override
。你说过“方法隐藏可以用于多态,是的”。那么是编译时多态性还是运行时多态性?@ShaileshJaiswal:请阅读该句后面的句子。谢谢Eric,我明白你的意思了。我读了这篇文章。方法隐藏在基类和派生类中可以有不同的签名吗?@ShaileshJaiswal:“新”方法应该与它隐藏的方法具有完全相同的签名;如果没有,编译器会给你一个警告,指出“new”是不必要的。