C# 方法签名中的新关键字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1014295/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:34:13  来源:igfitidea点击:

new keyword in method signature

c#methodskeyword

提问by p.campbell

While performing a refactoring, I ended up creating a method like the example below. The datatype has been changed for simplicity's sake.

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

I previous had an assignment statement like this:

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

MyObject myVar = new MyObject();

It was refactored to this by accident:

它被意外重构为:

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

This was a result of a cut/paste error on my part, but the newkeyword in private static newis valid and compiles.

这是我的剪切/粘贴错误的结果,但new关键字 inprivate static new有效并且可以编译。

Question: What does the newkeyword signify in a method signature? I assume it's something introduced in C# 3.0?

问题new关键字在方法签名中表示什么?我假设它是 C# 3.0 中引入的东西?

How does this differ from override?

这与 有override什么不同?

采纳答案by Kelsey

New keyword reference from MSDN:

来自 MSDN 的新关键字参考:

MSDN Reference

MSDN 参考

Here is an example I found on the net from a Microsoft MVP that made good sense: Link to Original

这是我在网上从 Microsoft MVP 中找到的一个很有意义的示例: 链接到原始

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

Override can only be used in very specific cases. From MSDN:

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

You cannot override a non-virtual or static method. The overridden base method must be virtual, abstract, or override.

您不能覆盖非虚拟或静态方法。重写的基本方法必须是虚拟的、抽象的或重写的。

So the 'new' keyword is needed to allow you to 'override' non-virtual and static methods.

因此,需要使用“new”关键字来“覆盖”非虚拟和静态方法。

回答by BFree

No, it's actually not "new" (pardon the pun). It's basically used for "hiding" a method. IE:

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

public class Base
{
   public virtual void Method(){}
}

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

If you then do this:

如果你然后这样做:

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

The method in the Base is the one that will be called, NOT the one in the derived.

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

Some more info: http://www.akadia.com/services/dotnet_polymorphism.html

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

Re your edit:In the example that I gave, if you were to "override" instead of using "new" then when you call b.Method(); the Derived class's Method would be called because of Polymorphism.

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

回答by jonnii

From the docs:

从文档:

If the method in the derived class is preceded with the new keyword, the method is defined as being independent of the method in the base class.

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

What this means in practice:

这在实践中意味着什么:

If you inherit from another class and you have a method that shares the same signature you can define it as 'new' so that it independent from the parent class. This means that if you have a reference to the 'parent' class then that implementation will be executed, if you have a reference to the child class then that implementation will be executed.

如果您从另一个类继承并且您有一个共享相同签名的方法,您可以将其定义为“新”,以便它独立于父类。这意味着如果您有对“父”类的引用,则将执行该实现,如果您有对子类的引用,则将执行该实现。

Personally I try to avoid the 'new' keyword as it normally means I've got my class hierarchy wrong, but there are times when it can be useful. One place is for versioning and backwards compatibility.

就我个人而言,我尽量避免使用“new”关键字,因为它通常意味着我的类层次结构错误,但有时它会很有用。一处用于版本控制和向后兼容性。

There's lot of information in the MSDN for this.

MSDN 中有很多关于此的信息

回答by Doug R

From MSDN:

MSDN

Use the new modifier to explicitly hide a member inherited from a base class. To hide an inherited member, declare it in the derived class using the same name, and modify it with the new modifier.

使用 new 修饰符显式隐藏从基类继承的成员。要隐藏继承的成员,请在派生类中使用相同的名称声明它,并使用 new 修饰符修改它。

回答by Robin Clowers

It means the method replaces a method by the same name inherited by the base class. In your case, you probably don't have a method by that name in the base class, meaning the new keyword is totally superfluous.

这意味着该方法替换了基类继承的同名方法。在您的情况下,您可能在基类中没有该名称的方法,这意味着 new 关键字完全是多余的。

回答by Dan Herbert

As others explained, it is used to hide an existing method. It is useful for overriding a method that isn't virtual in the parent class.

正如其他人所解释的,它用于隐藏现有方法。它对于覆盖父类中非虚拟的方法很有用。

Keep in mind that creating a "new" member is not polymorphic. If you cast the object to the base type, it will not use the derived type's member.

请记住,创建“新”成员不是多态的。如果将对象强制转换为基类型,则它不会使用派生类型的成员。

If you have a base class:

如果你有一个基类:

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

And then the derived class:

然后是派生类:

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

}

If you declare a type of DerivedTypeand then cast it, the method DoSomething()isn't polymorphic, it will call the base class' method, not the derived one.

如果您声明了一种类型DerivedType然后对其进行转换,则该方法DoSomething()不是多态的,它将调用基类的方法,而不是派生的方法。

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

回答by Don Cheadle

Long story short -- it's NOT required, it changes NO behavior, and it is PURELY there for readability.

长话短说——它不是必需的,它不会改变任何行为,它纯粹是为了可读性。

That's why in VS you will see a little squiggly, yet your code will compile and run perfectly fine and as expected.

这就是为什么在 VS 中您会看到一些波浪线,但您的代码将按预期编译和运行得非常好。

One has to wonder if it was really worth creating the newkeyword when all it means is the developer's acknowledging "Yes, I know I'm hiding a base method, yes I know I'm not doing anything related to virtualor overriden(polymorphism) -- I really want to just create it's own method".

人们不得不怀疑是否真的值得创建new关键字,因为它意味着开发人员承认“是的,我知道我隐藏了一个基本方法,是的,我知道我没有做任何与virtualoverriden(多态性)相关的事情——我真的很想创建它自己的方法”。

It's a bit bizarre to me, but maybe only because I come from a Javabackground and there's this fundamental difference between C#inheritance and Java: In Java, methods are virtual by default unless specified by final. In C#, methods are final/concrete by default unless specified by virtual.

这对我来说有点奇怪,但也许只是因为我来自Java背景,并且C#继承和之间存在这种根本区别Java:在 中Java,方法默认情况下是虚拟的,除非由final. 在 中C#,除非由 指定,否则默认情况下方法是最终/具体的virtual

回答by Overfilledwaistcoat

Be careful of this gotcha.
You have a method defined in an interface that is implemented in a base class. You then create a derived class that hides the interface's method, but don't specifically declare the derived class as implementing the interface. If you then call the method via a reference to the interface, the base class's method will be called. However if your derived class does specifically implement the interface, then its method will be called whichever type of reference is used.

小心这个陷阱。
您在基类中实现的接口中定义了一个方法。然后创建一个隐藏接口方法的派生类,但不要专门将派生类声明为实现该接口。如果随后通过对接口的引用调用该方法,则将调用基类的方法。但是,如果您的派生类确实专门实现了该接口,则无论使用哪种类型的引用,都将调用其方法。

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();

    }
}