C# 使用虚拟签名重写方法签名
众所周知,对类中的方法使用virtual关键字允许我们在其派生的子类中重写它。然而,方法仍然必须坚持相同的签名,例如返回值、参数等 问题:在C#中,我如何也覆盖签名?这可能吗C# 使用虚拟签名重写方法签名,c#,C#,众所周知,对类中的方法使用virtual关键字允许我们在其派生的子类中重写它。然而,方法仍然必须坚持相同的签名,例如返回值、参数等 问题:在C#中,我如何也覆盖签名?这可能吗 谢谢。这是不可能的。但是,如果需要,可以创建重载 编辑 让我反对新< /代码>,请考虑有一个基类对象和一个继承它的情况。通过将new放在试图“更改”方法签名的方法之前,实际上浪费了四个按键 public class Base { public string Foo () { return null; } } pu
谢谢。这是不可能的。但是,如果需要,可以创建重载 编辑
让我反对<代码>新< /代码>,请考虑有一个基类对象和一个继承它的情况。通过将
new
放在试图“更改”方法签名的方法之前,实际上浪费了四个按键
public class Base {
public string Foo () { return null; }
}
public class Inherited : Base {
public new int Foo () { return 0; }
}
现在,Inherited
有两种方法:
public string Foo () { return null; }
public int Foo () { return 0; }
您实际上并没有更改方法签名。因此,甚至不需要new
关键字。没有它,您将获得相同的效果:
public class Inherited : Base {
public int Foo () { return 0; }
}
new
的用途是:
但如果你不注意这个微妙之处,你会遇到问题。使用virtual
您将获得一个虚拟查找表,该表将把您的函数映射到正确的调用。使用new
,您将不会。如果在需要Base
对象的地方传入Inherited
(当然这会起作用),将调用Base
类的Foo()
!不是,继承了Foo()
的重写
这与覆盖虚拟成员的行为不同。
public static class MyClass {
public string MyMethod (Base @base) {
return @base.Foo ();
}
}
[Test]
public void then_it_should_return_non_null () {
var obj = new Inherited ();
var result = MyClass.MyMethod(obj); // obj will get upcasted to Base
Assert.That (result, Is.EqualTo(obj.Foo ())); // Assert fails!
}
[Test]
public void inherited_should_return_correct_value ()
{
var obj = new Inherited ();
var result = obj.Foo (); // will access the "new" method, hiding Base's implementation
Assert.That (result, Is.Not.Null); // Assert passes!
}
您可以使用new
关键字隐藏旧的实现。但是,基类将无法看到它
class Base {
public string Foo() { }
}
class Sub : Base {
new public int Foo() { }
}
new
仅当调用签名相同时才需要。此时您只是在创建一个新方法。但是,如果您只想创建一个具有新方法签名的新方法,然后调用base.OtherMethod(param1,param2)。。。你可以
我想指出的一点是,如果您打算创建一个与基类同名但签名不同的方法,但仍然希望调用基类,那么您可以
例如:
// In base class - note, the "virtual" isn't necessary.
public virtual void PostMessage(string message, DateTime entryDate) { ... }
然后你想。。。“哦,伙计,我希望这个基类有一个不需要日期的方法重载…我能做什么?!”
您正在谈论创建一种新方法。如果名称相同,但参数不同(返回类型、参数类型和参数数量),则实际上是重载。这不会更改签名。@JamesD'Angelo是的,它可以更改签名。它不会更改签名。它覆盖了一个非虚拟类成员。快速检查VS中的健全性会给我一个警告:“成员'foo.bar()'不会隐藏继承的成员。新关键字不是必需的。”@JamesD'Angelo它们是公共的吗?谢谢你的评论。我明白你的意思,但没有得到最后一句话“然后调用base.OtherMethod(param1,param2)…你可以。”你能给我一些想法吗?
// In base class - note, the "virtual" isn't necessary.
public virtual void PostMessage(string message, DateTime entryDate) { ... }
// In your sub-class.
public void PostMessage(string message)
{
base.PostMessage(message, DateTime.Now);
}