C#: オーバーロードされたメソッドに null を渡す - どのメソッドが呼び出されますか? 質問する

C#: オーバーロードされたメソッドに null を渡す - どのメソッドが呼び出されますか? 質問する

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

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

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

Method( null );

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

ベストアンサー1

それTypeAは とに依存しますTypeB

  • そのうちの 1 つだけが適用可能な場合 (たとえば、値型だが参照型であるため、nullからへの変換はありません)、適用可能なものに対して呼び出しが行われます。TypeBTypeA
  • TypeAそれ以外の場合は、との関係によって決まりますTypeB
    • TypeAからへの暗黙的な変換はあるが、 から への暗黙的な変換はない場合は、TypeBオーバーロード usingが使用されます。TypeBTypeATypeA
    • TypeBからへの暗黙的な変換はあるが、 から への暗黙的な変換はない場合は、TypeAオーバーロード usingが使用されます。TypeATypeBTypeB
    • そうしないと、呼び出しがあいまいになり、コンパイルに失敗します。

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

曖昧ではない例を次に示します。ここでは はTypeBから派生しており、これはからTypeAへの暗黙的な変換があることを意味しますが、その逆はありません。したがって、オーバーロード using が使用されます。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 つのクラスがその基本クラスで宣言されたメソッドをオーバーロードする場合)、まったく別の問題が発生し、引数ではなくメソッドのターゲットをキャストする必要があることに注意してください。

おすすめ記事