在方法签名中使用新关键字通常只是为了提高可读性?

the*_*ist 6 c# c#-4.0

我已经阅读了方法签名中的new关键字,并且已经在这篇文章中看到过以下示例,但我仍然不明白为什么要在方法签名中编写new关键字.如果我们省略它,它仍然会做同样的事情.它会编译.会有一个警告,但它会编译.

那么,写new 方法签名只是为了可读性?

public class A
{
   public virtual void One() { /* ... */ }
   public void Two() { /* ... */ }
}

public class B : A
{
   public override void One() { /* ... */ }
   public new void Two() { /* ... */ }
}

B b = new B();
A a = b as A;

a.One(); // Calls implementation in B
a.Two(); // Calls implementation in A
b.One(); // Calls implementation in B
b.Two(); // Calls implementation in B
Run Code Online (Sandbox Code Playgroud)

pho*_*oog 9

隐含在这个问题中:为什么new隐藏基类成员时不需要关键字?原因是脆弱的基类问题.假设你有一个库:

public class Base
{
    public void M() { }
}
Run Code Online (Sandbox Code Playgroud)

并且您已经在自己的代码库中派生了一个类:

public class Derived : Base
{
    public void N() { }
}
Run Code Online (Sandbox Code Playgroud)

现在,库作者发布了一个新版本,添加了另一种方法Base:

public class Base
{
    public void M() { }
    public void N() { }
}
Run Code Online (Sandbox Code Playgroud)

如果方法隐藏需要new关键字,那么您的代码现在无法编译!使新关键字可选意味着您现在拥有的所有内容都是一个值得担心的新警告.

编辑

正如Eric Lippert在评论中指出的那样,"担心的新警告"大大低估了警告的目的,即"挥动大红旗".我写这篇文章的时候一定很匆忙; 当人们反复地将警告视为可以容忍的烦恼而不是将其视为有用信息时,这是令人讨厌的.

编辑2

我终于找到了这个答案的来源,当然,这是Eric的帖子之一:https://stackoverflow.com/a/8231523/385844

  • 这是正确的答案,虽然我会补充一点:"new"是*optional*确实阻止了你所描述的*脆弱的基类构建中断*.但它还有另一个目的:它*告诉你*基类的提供者以一种直接影响你的方式搞乱了它,这是子类的作者.警告正在挥动一个大红旗,上面写着"嘿,派生的班级实施者!这里有一些重要的东西你需要注意!" 我们不会打破你的构建,但我们会让你知道它,以便你可以决定做什么. (7认同)

Wik*_*hla 5

我的猜测是C#设计师希望我们注意到不使用virtual,override我们不会得到多态行为.这就是大多数来自Java的人所期望的.如果new省略它会使编译器发出警告.