方法签名中的新关键字

在执行重构时,我最终创build了一个如下例所示的方法。 为简单起见,数据types已被更改。

我以前有一个这样的赋值语句:

MyObject myVar = new MyObject(); 

这是偶然的重构:

 private static new MyObject CreateSomething() { return new MyObject{"Something New"}; } 

这是我的一个剪切/粘贴错误的结果,但在newprivate static new关键字是有效和编译。

问题new关键字在方法签名中意味着什么? 我认为这是在C#3.0中引入的东西?

这与override有何不同?

来自MSDN的新关键字引用:

MSDN参考

以下是我在Microsoft MVP的networking上find的一个例子,它很有意义: Link to Original

 public class A { public virtual void One(); public void Two(); } public class B : A { public override void One(); public new void Two(); } B b = new B(); A a = b as A; a.One(); // Calls implementation in B a.Two(); // Calls implementation in A b.One(); // Calls implementation in B b.Two(); // Calls implementation in B 

覆盖只能在非常特殊的情况下使用。 来自MSDN:

您无法重写非虚拟或静态方法。 重写的基本方法必须是虚拟的,抽象的或重写的。

所以需要使用“新”关键字来“覆盖”非虚拟和静态的方法。

不,这其实不是“新”(原谅双关语)。 它基本上用于“隐藏”一种方法。 IE:

 public class Base { public virtual void Method(){} } public class Derived : Base { public new void Method(){} } 

如果你这样做:

 Base b = new Derived(); b.Method(); 

Base中的方法是被调用的方法,而不是派生的方法。

更多信息: http : //www.akadia.com/services/dotnet_polymorphism.html

重新编辑:在我给出的例子中,如果您要“覆盖”而不是使用“新”,那么当您调用b.Method(); 派生类的方法将因为多态而被调用。

正如其他人所解释的,它被用来隐藏现有的方法。 这对重写父类中不是虚拟的方法很有用。

请记住,创build“新”成员不是多态的。 如果将对象转换为基types,则不会使用派生types的成员。

如果你有一个基类:

 public class BaseClass { public void DoSomething() { } } 

然后派生类:

 public class DerivedType : BaseClass { public new void DoSomething() {} } 

如果声明了一个DerivedTypetypes然后DerivedType ,方法DoSomething()不是多态的,它将调用基类的方法,而不是派生的方法。

 BaseClass t = new DerivedType(); t.DoSomething();// Calls the "DoSomething()" method of the base class. 

从文档:

如果派生类中的方法以new关键字开头,则该方法被定义为独立于基类中的方法。

这在实践中意味着什么:

如果您从另一个类inheritance,并且您拥有共享相同签名的方法,则可以将其定义为“新”,以使其与父类无关。 这意味着如果你有一个对“父”类的引用,那么这个实现将被执行,如果你有一个对子类的引用,那么这个实现将被执行。

就我个人而言,我试图避免使用“新”关键字,因为它通常意味着我的类层次结构错误,但有时候它可能是有用的。 一个地方是版本和向后兼容。

MSDN中有很多这方面的信息。

这意味着该方法将用基类inheritance的相同名称replace一个方法。 在你的情况下,你可能没有在基类中的名称的方法,这意味着新的关键字是完全多余的。

长话短说 – 这不是必需的,它改变了没有行为,这是为了可读性。

这就是为什么在VS中你会看到一些小小的错误,但是你的代码将会被编译和运行,并且和预期的一样。

一个人不得不怀疑是否真的值得创buildnew关键字,当所有的意思是开发人员承认“是的,我知道我隐藏一个基本的方法,是的,我知道我没有做任何有关virtualoverriden (多态) – 我真的想要创build它自己的方法“。

这对我来说有点奇怪,但也许只是因为我来自Java背景, C#inheritance和Java之间存在这种根本区别:在Java ,除非final指定,否则方法默认为虚拟。 在C# ,默认情况下方法是final / concrete,除非由virtual指定。

来自MSDN :

使用新的修饰符来显式地隐藏从基类inheritance的成员。 要隐藏inheritance的成员,请使用相同名称在派生类中声明它,并使用新修饰符对其进行修改。

小心这个问题。
您有一个在基类中实现的接口中定义的方法。 然后创build一个隐藏接口方法的派生类,但不要特别声明派生类实现接口。 如果通过对接口的引用调用方法,则将调用基类的方法。 但是,如果你的派生类专门实现了接口,那么它的方法将被称为使用任何types的引用。

 interface IMethodToHide { string MethodToHide(); } class BaseWithMethodToHide : IMethodToHide { public string MethodToHide() { return "BaseWithMethodToHide"; } } class DerivedNotImplementingInterface : BaseWithMethodToHide { new public string MethodToHide() { return "DerivedNotImplementingInterface"; } } class DerivedImplementingInterface : BaseWithMethodToHide, IMethodToHide { new public string MethodToHide() { return "DerivedImplementingInterface"; } } class Program { static void Main() { var oNoI = new DerivedNotImplementingInterface(); IMethodToHide ioNoI = new DerivedNotImplementingInterface(); Console.WriteLine("reference to the object type DerivedNotImplementingInterface calls the method in the class " + oNoI.MethodToHide()); // calls DerivedNotImplementingInterface.MethodToHide() Console.WriteLine("reference to a DerivedNotImplementingInterface object via the interfce IMethodToHide calls the method in the class " + ioNoI.MethodToHide()); // calls BaseWithMethodToHide.MethodToHide() Console.ReadLine(); var oI = new DerivedImplementingInterface(); IMethodToHide ioI = new DerivedImplementingInterface(); Console.WriteLine("reference to the object type DerivedImplementingInterface calls the method in the class " + oI.MethodToHide()); // calls DerivedImplementingInterface.MethodToHide() Console.WriteLine("reference to a DerivedImplementingInterface object via the interfce IMethodToHide calls the method in the class " + ioI.MethodToHide()); // calls DerivedImplementingInterface.MethodToHide() Console.ReadLine(); } }