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

时间:2012-03-01 16:38:56

标签: c# polymorphism shadowing method-hiding

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

5 个答案:

答案 0 :(得分:16)

  

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。

  

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

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

答案 1 :(得分:4)

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

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

  

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

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

答案 2 :(得分:2)

这两个术语在C#中的含义相同。

方法隐藏==遮蔽。

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

阴影方法与基类完全分离 - 它是一种新方法。使用术语隐藏是因为它与基类的签名具有相同的签名并且正在“隐藏”它 - 它会破坏继承链。

答案 3 :(得分:2)

对于同一件事,它们只是两个不同的词,但在您最常使用它们的上下文中有所不同。通常,所谓的“隐藏”与多态性有关,但所谓的“遮蔽”则不是。

在C#用语中,当你说“隐藏”时,你通常会谈论继承,其中一个更加派生的方法“隐藏”来自普通继承方法调用链的基类方法。

当你说“影子”时,你通常会谈论范围:内部范围内的标识符是“遮蔽”更高范围的标识符。在其他语言中,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关键字只是清楚地说明了我们想要的是什么。

仅在X范围内的D.C()阴影类成员D.X中的

局部变量D.C()。在这种情况下,范围内有两件事可以合法地称为X,编译器需要规则来告诉它你的意思。 “更本地化”X会影响“较少本地化”D.X,这就是我们所得到的。

答案 4 :(得分:2)

隐藏C#(new modifier)的名称在VB.NET中被称为阴影(keyword Shadows)。

这可以被认为是多态性,只是在覆盖是“多态”的意义上,即静态或编译时。在调用虚函数的经典意义上,不是是一种多态性。