一尘不染

为什么我们需要new关键字,为什么默认行为是隐藏而不是覆盖?

c#

我在看这篇博客文章时有以下问题:

  • 我们为什么需要new关键字,仅仅是指定隐藏一个基类方法。我的意思是,为什么我们需要它?如果我们不使用override关键字,我们是否隐藏了基类方法?
  • 为什么C#中的默认值是隐藏而不是覆盖?设计者为什么要以这种方式实现它?

阅读 210

收藏
2020-05-19

共1个答案

一尘不染

好问题。让我重申一下。

为何完全隐藏另一个方法是合法的?

让我用一个例子回答这个问题。您具有CLR v1的接口:

interface IEnumerable
{
    IEnumerator GetEnumerator();
}

超。现在,在CLR v2的你有仿制药,你认为“男人,如果在V1恨不有仿制药,我会做这个的通用接口。但我没有。我应该做的东西,现在与它兼容即
通用的,所以这我获得了泛型的好处,而又不会失去与期望IEnumerable的代码的向后兼容性。”

interface IEnumerable<T> : IEnumerable
{
    IEnumerator<T> .... uh oh

您将如何调用的GetEnumerator方法IEnumerable<T>?记住,您 希望
它在非通用基本接口上隐藏GetEnumerator。除非您明确处于向后兼容的情况,否则您 永远不 希望调用该东西。

仅此一点就证明了方法的隐藏。有关方法隐藏的理由的更多想法,请参阅我关于该主题的文章

为什么没有“新”的隐藏会引起警告?

因为我们希望引起您注意,所以您隐藏了某些东西,并且可能是意外地在做。 请记住,您可能是由于别人对基类的编辑而不是您对派生类的编辑而意外地隐藏了某些东西。

为什么隐藏没有“新”内容的警告而不是错误?

相同的原因。您可能会意外隐藏了某些东西,因为您刚刚获得了新版本的基类。这事儿常常发生。FooCorp创建基类B。BarCorp使用方法Bar创建派生类D,因为他们的客户喜欢该方法。FooCorp看到了这一点,然后说,嘿,这是一个好主意,我们可以将该功能放在基类上。他们这样做并发布了新版本的Foo.DLL,当BarCorp选择新版本时,如果告诉他们他们的方法现在隐藏了基类方法,那就太好了。

我们希望这种情况只是 警告 而不是 错误, 因为使其成为错误意味着 这是脆性基类问题的另一种形式
。C#经过精心设计,以便当有人对基类进行更改时,对使用派生类的代码的影响减至最小。

为什么要隐藏而不是覆盖默认值?

因为虚拟覆盖很 危险 。虚拟覆盖允许派生类更改已编译为使用基类的代码的行为。做一些危险的喜欢做一个覆盖应该是你做的东西 有意识刻意
,不是偶然的。

2020-05-19