使用virtual覆盖方法签名

时间:2012-10-19 01:01:48

标签: c#

众所周知,对类中的方法使用virtual关键字允许我们在派生的子类中覆盖它。但是,方法仍然必须坚持相同的签名,例如返回值,参数等。

问题:在C#中,我怎样才能覆盖签名?这有可能吗?

感谢。

4 个答案:

答案 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; }
}

使用newoverride 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)

您正在谈论创建新方法。如果名称相同,但参数不同(返回类型和参数的类型和参数数量),实际上您正在超载。