2

誰もが知っているように、クラスのメソッドに virtual キーワードを使用すると、その派生サブクラスでそれをオーバーライドできます。ただし、メソッドは、戻り値、引数など、同じ署名に固執する必要があります。

質問: C# では、どうすれば署名もオーバーライドできますか? これは可能ですか?

ありがとう。

4

4 に答える 4

5

それは不可能。ただし、必要に応じてオーバーロードを作成できます。

編集

に対して私newの主張をするために、基本オブジェクトとそれを継承するオブジェクトがある場合を考えてください。newメソッド シグネチャを「変更」しようとしているメソッドの前に配置すると、実際には 4 つのキー ストロークが無駄になります。

public class Base {
    public string Foo () { return null; }
}

public class Inherited : Base {
    public new int Foo () { return 0; }
}

現在、次のInherited2 つの方法があります。

public string Foo () { return null; }
public int Foo () { return 0; }

メソッドのシグネチャを実際に変更しているわけではありません。したがって、newキーワードは必要ありません。それがなくても同じ効果が得られます:

public class Inherited : Base {
    public int Foo () { return 0; }
}

の使用は、基本クラスの非仮想メンバーnewをオーバーライドすることです。

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! 
}
于 2012-10-19T01:04:03.450 に答える
0

newキーワードを使用して、古い実装を非表示にすることができます。ただし、基本クラスはそれを見ることができません。

class Base {
   public string Foo() { }
}

class Sub : Base {
   new public int Foo() { }
}

new呼び出し署名が同じ場合にのみ必要です。

于 2012-10-19T01:04:16.603 に答える
0

その時点で、あなたは新しいメソッドを作成しているだけです。しかし、単純に新しいメソッド シグネチャを使用して新しいメソッドを作成したい場合は、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);
}
于 2012-10-19T01:04:35.913 に答える
0

新しいメソッドの作成について話している。名前は同じでもパラメーターが異なる場合 (戻り値の型とパラメーターの型とパラメーターの数)、実際にはオーバーロードしています。

于 2012-10-19T01:28:09.520 に答える