正如每个人都知道在类中使用virtual关键字允许我们在其派生的子类中覆盖它。然而,方法仍然必须坚持相同的签名,例如返回值,参数等。使用虚拟覆盖方法签名
问题:在C#中,我怎样才能重写签名呢?这可能吗?
谢谢。
正如每个人都知道在类中使用virtual关键字允许我们在其派生的子类中覆盖它。然而,方法仍然必须坚持相同的签名,例如返回值,参数等。使用虚拟覆盖方法签名
问题:在C#中,我怎样才能重写签名呢?这可能吗?
谢谢。
这是不可能的。如果你需要的话,你可以创建一个重载。
编辑
为了使我的情况下对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!
}
您可以用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) { ... }
那你认为......“哦,我想这个基类曾经对自己没有要求的日期是方法的重载......我该怎么办? !”
// In your sub-class.
public void PostMessage(string message)
{
base.PostMessage(message, DateTime.Now);
}
感谢您的评论。我看到你在说什么,但没有得到最后的声明“,然后调用base.OtherMethod(param1,param2)...你可以。”你能给我一些想法吗? –
我会编辑答案更清晰。 –
您正在讨论创建新方法。如果名称相同,但参数不同(返回类型和参数的类型和参数数量),则实际上会超载。
虽然这并不会改变签名。 –
@ JamesD'Angelo是的,它可以改变签名。 –
@ JamesD'Angelo http://msdn.microsoft.com/en-us/library/435f1dw2.aspx –