【问题标题】:C#: public new string ToString() VS public override string ToString()C#:公共新字符串 ToS​​tring() VS 公共覆盖字符串 ToS​​tring()
【发布时间】:2010-11-04 03:09:18
【问题描述】:

我想在我的一个类中重新定义 ToString() 函数。

我写的

public string ToString()

... 它工作正常。但是 ReSharper 告诉我将其更改为

public new string ToString() 

或

public override string ToString()

有什么区别?为什么 C# 需要这样的东西?

【问题讨论】:

  • +1 以合理的方式拼写你的名字;-p(这是一个合理的问题......)

标签: c# oop


【解决方案1】:

如果您使用public string ToString(),则不清楚您打算做什么。如果你的意思是通过多态来改变ToString 的行为,那么override。您可以添加new ToString(),但这太愚蠢了。不要那样做!

不同之处在于你这样做时会发生什么:

MyType t = new MyType();
object o = t;
Console.WriteLine(t.ToString());
Console.WriteLine(o.ToString());

如果你override,两者都会输出你的新版本。如果你new,只有第一个会使用你的新版本;第二个将使用原始实现。

我不认为我曾经看到有人在ToString() 上使用方法隐藏(又名new)。

【讨论】:

  • 不幸的是,我看到了几个隐藏在 C# 中的方法示例。他们都不漂亮。
  • 哦,当然,方法隐藏并没有那不常见 - 我只是从未在 ToString() 上见过它;-p 但是 DbConnection.CreateCommand 是更广泛的背景...
  • 感谢您的解释。但我有一个简单的问题,如果使用情况得到很好的控制(从不在父级上调用 ToString())。该方法在运行时隐藏得更快吗?我想说应该是!
  • @Niklaos 我对此表示怀疑;即使是这样,也不会太多 - 实例方法总是使用“callvirt”,即使对于非虚拟方法也是如此。 JIT 有可能对其进行优化,但是...
【解决方案2】:

问题在于 ToString 是一个虚方法。为了覆盖 C# 中的虚拟方法,您需要指定 override 关键字。

您几乎肯定不想要“新”版本。 .

【讨论】:

    【解决方案3】:

    new modifier 将隐藏或“隐藏”基类中具有相同签名的成员,而 overriding 提供从基类继承的成员的新实现。这是一个good article,关于阴影和覆盖之间的区别。

    【讨论】:

      【解决方案4】:

      您想要覆盖。隐藏在您的案例中(使用“新”)确实没有任何优势。

      这是一篇关于the differences between overriding and hiding的文章。

      【讨论】:

        【解决方案5】:

        C# 不需要它; Resharper 可以。它需要它,因为这两个关键字代表明显不同的行为,如果您不指定,阅读您的代码的人可能不完全清楚默认行为是什么(它是new。)

        在这种情况下,您显然想要覆盖。

        【讨论】:

        • 实际上,即使没有 R#,您也会收到关于此的警告。 语言不需要它,但即使是“express”(免费)IDE 也知道这是一个坏主意。
        【解决方案6】:

        ToString 是基类中的虚方法。要使当前成员覆盖该实现,请添加 override 关键字。否则添加新关键字。

        【讨论】:

          【解决方案7】:

          你所做的一切都取决于你想要的行为。 This article 解释了 ToString 的行为是如何工作的,具体取决于您定义方法的方式以及您调用 ToString 的类层次结构中的哪个级别。

          【讨论】:

            【解决方案8】:

            我个人的建议是不要使用隐藏;它会导致很多歧义,但解决的很少。

            【讨论】:

              【解决方案9】:

              ToString() 方法可用于 .NET 中的每种类型,因为此方法在 System.Object 基类中定义为虚拟方法,并且所有类型都直接或间接继承自 System。目的。如果 ToString() 方法的默认实现不能满足您的目的,您可能希望覆盖(使用 override 关键字)或隐藏(使用 new 关键字)它。

              我遇到了以下 2 篇优秀的文章,解释了重写 ToString() 方法的原因,以及方法隐藏和方法重写之间的区别。还有一个关于相同概念的 youtube 视频
              Reason to override ToString()
              Difference between method hiding and method overriding

              【讨论】:

                猜你喜欢
                • 2014-05-25
                • 2017-05-22
                • 1970-01-01
                • 2023-04-01
                • 1970-01-01
                • 2011-11-26
                • 2011-02-15
                • 2021-05-19
                • 2023-03-29
                相关资源
                最近更新 更多