namespace BarCorp
{
public class Blobber : FooCorp.Frobber
{
public void Blobnicate() { ... }
...
Foo公司意识到人们喜欢Blobnicate,他们决定运送Foo.DLL v2.0:
namespace FooCorp
{
public class Frobber
{
public void Frobnicate() { ... }
public void Blobnicate() { ... }
...
当你得到一个新版本的Foo.DLL并重新编译时, you want to be told that you are now accidentally introducing a new method that shadows a base class method. 这可能是一个危险的事情;你的类是在假设基类是Frobnicator的情况下编写的,但显然现在它也是一个Blobnicator!这个事实可能会破坏您的客户,他们可能会在打算调用派生类版本时意外调用基类版本 .
但是,除非您确实需要隐藏该成员,否则通常最好使用 virtual/override 以便以多态方式使用该成员 . 通过隐藏, new 成员仅通过派生类的引用使用 . 如果您通过基本引用工作,您将继续获得基本行为,这可能是意外的 .
class Foo
{
public void M() { Console.WriteLine("Foo"); }
}
class Bar : Foo
{
public new void M() { Console.WriteLine("Bar"); }
}
Bar bar = new Bar();
bar.M(); // writes Bar
Foo foo = new Bar(); // still an instance of Bar
foo.M(); // writes Foo, does not use "new" method defined in Bar
相反,如果在 Foo 中使用 virtual 和 Bar 中的 override 声明了方法,那么在任何一种情况下,方法调用都将始终为"Bar" .
3 回答
正如您所注意到的,不需要新功能 . 它是可选的,如果你不使用它,你会收到警告 . 你完全正确地注意到这是一个奇怪的设计决定 .
此设计决策的目的是帮助缓解一类被称为“脆弱基类”问题的问题 . 这是该问题的一个版本:
Foo Corporation创建了一个类Frobber并将其发布到Foo.DLL 1.0版中:
你工作的律师事务所,制作Blobbers . Blobber可以做Frobber可以做的所有事情,但此外,它也可以做Blobnicate . 所以你决定从FooCorp重新使用Frobnicate的实现,并添加一些额外的功能:
Foo公司意识到人们喜欢Blobnicate,他们决定运送Foo.DLL v2.0:
当你得到一个新版本的Foo.DLL并重新编译时, you want to be told that you are now accidentally introducing a new method that shadows a base class method. 这可能是一个危险的事情;你的类是在假设基类是Frobnicator的情况下编写的,但显然现在它也是一个Blobnicator!这个事实可能会破坏您的客户,他们可能会在打算调用派生类版本时意外调用基类版本 .
我们使"new"可选,因此在不更改源代码的情况下隐藏基类方法是合法的 . 如果我们将其设为非法,那么FooCorp会因升级而破坏您的构建 . 但我们会发出警告,以便您知道您可能会意外地这样做 . 然后,您可以仔细检查代码;如果您确定您的Blobnicate实现现在是多余的,则可以将其删除 . 如果仍然良好,您可以将其标记为"new"并消除警告 .
合理?这是C#的一个微妙特性,使其适用于大规模多版本组件导向软件 .
使用
new
的好处是让您的意图明确 .但是,除非您确实需要隐藏该成员,否则通常最好使用
virtual/override
以便以多态方式使用该成员 . 通过隐藏,new
成员仅通过派生类的引用使用 . 如果您通过基本引用工作,您将继续获得基本行为,这可能是意外的 .相反,如果在
Foo
中使用virtual
和Bar
中的override
声明了方法,那么在任何一种情况下,方法调用都将始终为"Bar" .new
关键字允许您在意图中具体 .虽然默认行为是在没有new关键字的情况下隐藏基类的成员,但是无法确定是否确实要隐藏该成员,或者您是否真的想要覆盖该成员 .
明确表达总是更好 . 这样,下一个开发人员就会确切地知道你的意图 .