37

C#メソッドのオーバーロードされたバージョンが2つあるとします。

void Method( TypeA a ) { }
void Method( TypeB b ) { }

私は次のようにメソッドを呼び出します:

Method( null );

メソッドのどのオーバーロードが呼び出されますか?特定のオーバーロードが呼び出されるようにするにはどうすればよいですか?

4

6 に答える 6

73

とに依存しTypeAますTypeB

  • それらの1つだけが該当する場合(たとえば、値型であるが参照型であるため、からnullへの変換はありません)、該当するものが呼び出されます。TypeBTypeA
  • TypeAそれ以外の場合は、との間の関係に依存しTypeBます。
    • からへの暗黙の変換はあるが、からTypeATypeBの暗黙の変換がない場合は、を使用TypeBTypeAたオーバーロードTypeAが使用されます。
    • からへの暗黙の変換はあるが、からTypeBTypeAの暗黙の変換がない場合は、を使用TypeATypeBたオーバーロードTypeBが使用されます。
    • そうしないと、呼び出しがあいまいになり、コンパイルに失敗します。

詳細なルールについては、C#3.0仕様のセクション7.4.3.4を参照してください。

これは、あいまいでない例です。ここでTypeBは、から派生しています。つまり、からへTypeAの暗黙の変換がありますが、その逆はありません。したがって、を使用した過負荷が使用されます。TypeBTypeATypeB

using System;

class TypeA {}
class TypeB : TypeA {}

class Program
{
    static void Foo(TypeA x)
    {
        Console.WriteLine("Foo(TypeA)");
    }

    static void Foo(TypeB x)
    {
        Console.WriteLine("Foo(TypeB)");
    }

    static void Main()
    {
        Foo(null); // Prints Foo(TypeB)
    }
}

一般に、他の点ではあいまいな呼び出しが発生した場合でも、特定のオーバーロードが使用されるようにするには、次のようにキャストします。

Foo((TypeA) null);

また

Foo((TypeB) null);

これが宣言クラスの継承を伴う場合(つまり、1つのクラスがその基本クラスによって宣言されたメソッドをオーバーロードしている場合)、他の問題が発生し、引数ではなくメソッドのターゲットをキャストする必要があることに注意してください。

于 2009-04-05T19:51:09.527 に答える
5

Jon Skeet は、既定でどのオーバーロードが選択されるかについて既に回答していますが、特定のオーバーロードが確実に呼び出されるようにしたい場合は、キャストよりも名前付きパラメーターを使用する方がよい場合がよくあります。

あなたが持っている場合:

void Method( TypeA a ) { }
void Method( TypeB b ) { }

電話Method(a: null);するか、Method(b: null);

于 2015-04-22T12:29:15.100 に答える
1

あいまいな呼び出し。(コンパイル時エラー)。

于 2009-04-05T19:50:15.283 に答える