在c#中使用新关键字

我有两节课

class A { public virtual void Metod1() { Console.WriteLine("A.Method1"); } } class B : A { public new void Metod1() { Console.WriteLine("B.Method1"); } } 

然后我编写一些代码来声明这些类的实例,并调用它们的方法

  static void Main(string[] args) { A a = new B(); a.Metod1(); B b = new B(); b.Metod1(); Console.ReadKey(); } 

我给出了以下结果:

 A.Method1 B.Method1 

但是当我从B类的签名方法1中删除关键字new并运行Main方法时,我得到了相同的结果。 问题:方法签名中的新关键字是否只是为了更好的可读性?

编辑:是否存在我们离不开新关键字的情况?

是的,你是对的,这是为了在这种情况下更好的可读性。

但仔细检查一下,在隐藏基本方法时应该警告不使用new。

你可以在这里阅读更多: http : //msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx

关键字让代码阅读器知道此方法将在其基础中隐藏具有相同名称的方法。 即使你忽略它,编译器也会以同样的方式对待它,但是警告你。

由于您将方法声明为虚拟 ,因此在编译时会收到此警告:

‘B.Metod1()’隐藏了inheritance成员’A.Metod1()’。 要使当前成员覆盖该实现,请添加override关键字。 否则添加新关键字。

但是,如果通过删除virtual更改声明:

  • A没有虚拟的声明

     class A { public void Metod1() { Console.WriteLine("A.Method1"); } } class B: A { public void Metod1() { Console.WriteLine("B.Method1"); } } 

仍然会编译,但警告信息将是:

‘B.Metod1()’隐藏了inheritance成员’A.Metod1()’。 如果要隐藏,请使用new关键字。

无论如何,如上所述:

  • 测试代码

     var b=new B(); b.Metod1(); (b as A).Metod1(); 

将输出:

 B.Method1
 A.Method1

但是,如果您声明如下:

  • B 覆盖声明

     class A { public virtual void Metod1() { Console.WriteLine("A.Method1"); } } class B: A { public override void Metod1() { Console.WriteLine("B.Method1"); } } 

然后输出将是:

 B.Method1
 B.Method1

这是因为基类的Method1不仅被隐藏,而且派生类覆盖

如果Method1是抽象类中的抽象方法,那么您不能只使用new的情况是:

  • 必须在派生类中使用覆盖的代码

     abstract class A { public abstract void Metod1(); } class B: A { public override void Metod1() { // use `new` instead of `override` would not compile Console.WriteLine("B.Method1"); } } 

在这种情况下,您不能只使用new ,因为A要求派生类重写Method1

知道何时使用覆盖和新关键字(C#编程指南)

在C#中,派生类中的方法可以与基类中的方法具有相同的名称。 您可以使用new和override关键字指定方法的交互方式。 override修饰符扩展基类方法, new修饰符隐藏它

通过使用new,您断言您知道它修改的成员隐藏了从基类inheritance的成员