New 不是必需的,正如您所指出的。它是可选的,如果你不使用它,你会得到一个警告。您完全正确地注意到,乍一看这是一个奇怪的设计决定。
此设计决策的目的是帮助缓解称为“脆性基类”问题的一类问题。这是该问题的一个版本:
Foo Corporation 创建了一个 Frobber 类并在 Foo.DLL 版本 1.0 中发布它:
namespace FooCorp
{
public class Frobber
{
public void Frobnicate() { ... }
...
您为之工作的 Bar Corporation 生产 Blobbers。 Blobber 可以做 Frobber 可以做的所有事情,但除此之外,它也可以 Blobnicate。所以你决定重用 FooCorp 的 Frobnicate 实现,并添加一些额外的功能:
namespace BarCorp
{
public class Blobber : FooCorp.Frobber
{
public void Blobnicate() { ... }
...
Foo Corporation 意识到人们喜欢 Blobnicate,因此他们决定发布 Foo.DLL v2.0:
namespace FooCorp
{
public class Frobber
{
public void Frobnicate() { ... }
public void Blobnicate() { ... }
...
当你得到一个新版本的 Foo.DLL 并重新编译时,你想被告知你现在不小心引入了一个隐藏基类方法的新方法。这可能是一件危险的事情去做;您的类是在假设基类是 Frobnicator 的情况下编写的,但显然现在它也是 Blobnicator !这一事实可能会破坏您的客户,他们可能会在打算调用您的派生类版本时意外调用基类版本。
我们将“new”设为可选,以便您在不更改源代码的情况下合法隐藏基类方法。如果我们将其设为非法,那么 FooCorp 的升级会破坏您的构建。 但我们将其设为警告,以便您知道您可能会不小心这样做。然后您可以仔细检查代码;如果你决定你的 Blobnicate 实现现在是多余的,你可以删除它。如果还不错,可以将其标记为“新”并消除警告。
有意义吗?这是 C# 的微妙特性之一,使其适用于大型多版本面向组件软件。