方法签名中的新关键字

p.c*_*ell 112 c# methods keyword

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

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

MyObject myVar = new MyObject();
Run Code Online (Sandbox Code Playgroud)

它是偶然重构的:

private static new MyObject CreateSomething()
{
  return new MyObject{"Something New"};
}
Run Code Online (Sandbox Code Playgroud)

这是我的剪切/粘贴错误的结果,但new关键字in private static new有效并编译.

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

这有override什么不同?

Kel*_*sey 98

来自MSDN的新关键字参考:

MSDN参考

这是我在网上从微软MVP中找到的一个很有意义的例子: 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
Run Code Online (Sandbox Code Playgroud)

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

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

因此需要'new'关键字来"覆盖"非虚拟和静态方法.

  • 我只是运行你的样本..它会覆盖你甚至不指定"新",对吧? (4认同)
  • “虽然您可以在不使用 new 修饰符的情况下隐藏成员,但您会收到编译器警告。” 根据链接的文档。因此,关键字明确表示您打算隐藏,并且不会发出警告。 (3认同)
  • 完全是@MichaelSync,为什么我们需要提到新关键字? (2认同)
  • -1 -> 根本不需要 - 行为将是相同的。新手很困惑什么是“new”,但我认为它实际上只是为了可读性 - 编译器只是警告你,当你调用与基类同名的派生类方法时,你不会得到基类的方法你可能会认为......这很奇怪......纯粹是为了可读性? (2认同)

BFr*_*ree 59

不,它实际上不是"新的"(原谅双关语).它基本上用于"隐藏"一种方法.IE:

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

public class Derived : Base
{
   public new void Method(){}
}
Run Code Online (Sandbox Code Playgroud)

如果你这样做:

Base b = new Derived();
b.Method();
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @MichaelSync如果省略单词"override",则默认行为为"new",例如方法隐藏.因此,您将新单词留下的事实没有任何区别. (2认同)

Dan*_*ert 22

正如其他人所解释的那样,它用于隐藏现有方法.它可用于覆盖父类中非虚拟的方法.

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

如果你有一个基类:

public class BaseClass
{
    public void DoSomething() { }
}
Run Code Online (Sandbox Code Playgroud)

然后是派生类:

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

}
Run Code Online (Sandbox Code Playgroud)

如果声明一个类型DerivedType然后再强制它,那么该方法DoSomething()不是多态的,它将调用基类的方法,而不是派生的方法.

BaseClass t = new DerivedType();
t.DoSomething();// Calls the "DoSomething()" method of the base class.
Run Code Online (Sandbox Code Playgroud)

  • 我认为你的第二段指的是整个主题.当处理来自**基类引用**的调用时,"new"不是多态的...即.您可以在拨打电话时获得***."覆盖"是多态的...即.你得到*类层次结构*指定的内容. (2认同)

jon*_*nii 7

来自文档:

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

这在实践中意味着什么:

如果从其他类继承并且您有一个共享相同签名的方法,则可以将其定义为"new",以使其独立于父类.这意味着如果您有对'parent'类的引用,那么将执行该实现,如果您有对子类的引用,那么将执行该实现.

我个人试图避免使用'new'关键字,因为它通常意味着我的类层次结构错误,但有时它可能有用.一个地方是版本控制和向后兼容性.

MSDN中有很多关于此的信息.


Don*_*dle 7

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

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

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

这对我来说有点奇怪,但也许只是因为我来自一个背景,继承和Java之间存在根本区别: 在 中,方法默认是虚拟的,除非 指定。在 中,方法默认是最终/具体的,除非由 指定。C#JavaJavafinalC#virtual


归档时间:

查看次数:

79069 次

最近记录:

8 年,11 月 前