众所周知,对类中的方法使用virtual关键字允许我们在派生的子类中覆盖它。但是,方法仍然必须坚持相同的签名,例如返回值,参数等。
问题:在C#中,我怎样才能覆盖签名?这有可能吗?
感谢。
答案 0 :(得分:5)
这是不可能的。但是,如果需要,可以创建一个重载。
修改强>
为了使我的案例针对new
,请考虑你有一个基础对象的情况,以及一个继承它的情况。通过在您尝试“更改”方法签名的方法之前放置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
是override a non-virtual member of a base class:
public class Base {
public string Foo () { return null; }
}
public class Inherited : Base {
public new string Foo () { return "Something else..."; }
}
但是如果你不注意这个微妙的话,你会遇到这个问题。使用virtual
,您将获得一个虚拟查找表,将您的函数映射到正确的调用。使用new
,您不会。如果你传递Inherited
需要Base
对象的地方(当然这会有效),Base
课程的Foo()
将被调用!不,Inherited
“覆盖”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!
}
答案 1 :(得分:0)
您可以使用new
关键字隐藏旧实现。但是,基类将无法看到它。
class Base {
public string Foo() { }
}
class Sub : Base {
new public int Foo() { }
}
只有在呼叫签名相同的情况下才需要 new
。
答案 2 :(得分:0)
那时你正在制作一种新方法。但是,如果你想简单地用新方法签名创建一个新方法,然后调用base.OtherMethod(param1,param2)......你可以。
我想说的是,如果你打算创建一个与基类同名的方法,但是使用不同的签名但是你仍然只想调用基类< / strong>,那么你可以。
例如:
// 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);
}
答案 3 :(得分:0)
您正在谈论创建新方法。如果名称相同,但参数不同(返回类型和参数的类型和参数数量),实际上您正在超载。