【问题标题】:Is using new keyword in method signature generally just for readability?在方法签名中使用 new 关键字通常只是为了可读性吗?
【发布时间】:2012-03-01 08:41:02
【问题描述】:

我已经阅读了new关键字在方法签名中,并在this帖子中看到了下面的示例,但我仍然不明白为什么要写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

【问题讨论】:

  • new 用于定义 Class 的新实例。对于 C# StringBuilder strb 中的对象也是如此;如果你没有像我们说的那样“新建”它会出错所以你创建它的一个实例例如 strb = new StringBuilder(1000) 例如
  • 还看看你的例子,死者从我看到的东西中得到的是 public override void One();公共新无效二();看看基本的 OOP 原则,网上也有很多教程
  • @DJKRAZE 对new 的使用与创建对象无关:msdn.microsoft.com/en-us/library/…
  • theateist,我认为您所询问的 new 关键字的混淆部分是由于缺乏声明的方法实现。我将编辑您的示例代码。
  • phoog,你是对的。我还编辑了我的帖子 - 添加了在方法签名中

标签: c# c#-4.0


【解决方案1】:

是的,它只是为了便于阅读。

在子类的方法签名中有或没有它的功能是相同的。

...还没有人站出来说,因为他们试图指出你为什么仍然想使用它。但任何使用它的理由都是为了支持可读性

【讨论】:

    【解决方案2】:

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

    public class Base
    {
        public void M() { }
    }
    

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

    public class Derived : Base
    {
        public void N() { }
    }
    

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

    public class Base
    {
        public void M() { }
        public void N() { }
    }
    

    如果方法隐藏需要 new 关键字,您的代码现在无法编译!将新关键字设为可选意味着您现在需要担心的只是一个新的警告。

    编辑

    正如 Eric Lippert 在他的评论中指出的那样,“需要担心的新警告”大大低估了警告的目的,即“挥舞大红旗”。我写的时候一定很着急;当人们反射性地将警告视为可以容忍的烦恼而不是将其视为有用的信息时,这很烦人。

    编辑 2

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

    【讨论】:

    • 这是正确的答案,但我想补充一点:“新”是 可选 确实可以防止 脆弱的基类构建中断你描述的。但它还有另一个目的:它通知您您的基类的提供者以直接影响您(子类的作者)的方式对其进行了处理。警告挥舞着一个大红旗,上面写着“嘿,派生类实现者!这里发生了一些重要的事情,你需要注意!”我们不会破坏您的构建,但我们会通知您,以便您决定要做什么。
    • @EricLippert 感谢您指出这一点。有关其他 cmets,请参阅编辑后的帖子。
    • “脆弱的基类构建中断”我发现了一个新的绕口令。
    • 所以...答案是Yes 这不是必需的
    • @mmcrae 问题不是“是否需要”;问题是“它只是为了可读性”——答案是No
    【解决方案3】:

    我的猜测是 C# 设计者希望我们知道,如果不使用 virtualoverride,我们将不会获得多态行为。这是大多数来自 Java 的人所期望的。 new 清楚地表明了这一点,因为省略它会导致编译器发出警告。

    【讨论】:

      【解决方案4】:

      这不是必需的,但我强烈推荐它。

      MSDN

      声明的变量与基类中的变量同名。但是,没有使用 new 关键字。此警告通知您应该使用 new;该变量被声明为好像在声明中使用了 new 一样。

        public static int i = 2;   // CS0108, use the new keyword
        // the compiler parses the previous line as if you had specified:
        // public static new int i = 2;
      

      【讨论】:

      • @DJ 它的编译器警告(CS0108)和概念相同。他们没有给出所有案例的例子。
      【解决方案5】:

      不,这不是为了“可读性”!在这里明确说明,您不想重写继承的虚拟消息或“遮蔽”继承的方法,但真的想给出一个方法的新实现。

      【讨论】:

      • 为了可读性。没有new,语义完全相同。
      • 再一次,当我们阅读代码时,它就很清楚了。它提醒我或谁读过代码,基类中存在同名的方法、变量或属性,对吧?
      • @theate - 它会抑制警告。
      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 2014-05-03
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多