C#中的覆盖和新关键字有什么区别?

jay*_*yco 70 .net c# oop

在类层次结构中定义方法时,C#中的overridenew关键字有什么区别?

Bri*_*ham 88

以下页面很好地总结了您的问题.

知道何时使用覆盖和新关键字

摘要

覆盖:当在派生类中重写基类的方法时,即使调用代码没有"知道"该对象是派​​生类的实例,也会使用派生类中的版本.

新增:如果使用new关键字而不是override,派生类中的方法不会覆盖基类中的方法,它只会隐藏它.

如果未指定new或覆盖,则结果输出与指定new相同,但您也会收到编译器警告(因为您可能不知道您在基类中隐藏了一个方法方法,或者你可能想要覆盖它,只是忘了包含关键字).

覆盖:与基类中的virtual/abstract/override类型的方法一起使用

:当基类没有将方法声明为virtual/abstract/override时

  • 您能否在此处提供重要信息?它有助于保持信息在这里并防止链接腐烂(不太可能与MSDN博客,但你永远不知道). (9认同)
  • 大声笑"不太可能"我得到一个重定向,然后"访问被拒绝您没有权限查看/下载此项目." (3认同)
  • @tobsen我将MSDN链接更新到新页面. (3认同)

Ry-*_*Ry- 68

new将使用一个全新的方法(可能具有或不具有相同的签名)来遮蔽该方法,而不是覆盖它(在这种情况下,新方法必须具有相同的签名),这意味着多态将不起作用.例如,您有以下类:

class A {
    public virtual int Hello() {
        return 1;
    }
}

class B : A {
    new public int Hello(object newParam) {
        return 2;
    }
}

class C : A {
    public override int Hello() {
        return 3;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你这样做:

A objectA;
B objectB = new B();
C objectC = new C();

Console.WriteLine(objectB.Hello(null)); // 2
Console.WriteLine(objectC.Hello()); // 3

objectA = objectB;

Console.WriteLine(objectA.Hello()); // 1

objectA = objectC;

Console.WriteLine(objectA.Hello()); // 3
Run Code Online (Sandbox Code Playgroud)

由于您可以使用定义新方法签名new,因此编译器无法知道实例A实际上是实例,B并且新方法B定义应该可用.new可以在父对象的方法,属性,字段或事件未声明时使用virtual,并且由于缺少virtual编译器将不会"查找"继承的方法.随着virtualoverride,但是,它的工作原理.

我强烈建议你避免new; 充其量,这是令人困惑的,因为你正在定义一个名称可以被识别为其他东西的方法,最坏的情况是,它可以隐藏错误,引入看似不可能的错误,并使扩展功能变得困难.

  • 这应该是公认的答案.它实际上通过实例解释了差异是什么以及影响.接受的答案很模糊. (11认同)

Dha*_*jay 9

看起来像一个老问题,让我尝试一个不同的答案:

  1. new :正如名称所示,它是继承层次结构系列中的新成员,这将用作进一步向下链的基本成员(如果标记为虚拟).

  2. override :这意味着我不接受我父类的成员实现,我将采取不同的做法.