5

次のコードは、コンパイル時に「あいまいな呼び出し一致」をスローします。

class ABC{}
class DEF{}
class Program
{
    static void Main(string[] args)
    {
        Debug.WriteLine(func(null));
    }
    static string func(ABC abc)
    {
        return "";
    }
    static string func(DEF def)
    {
        return "";
    }
}

ただし、次のコードは正常にコンパイルおよび実行されます。

static void Main(string[] args)
{
    Debug.WriteLine(func(null));
}
static string func(int? abc)
{
    return "function a";
}
static string func(float? def)
{
    return "function b";
}

出力中

function a

C# は、2 番目の例でどの関数を選択するかをどのように判断するのでしょうか?

4

1 に答える 1

12

コンパイラがこのような関数呼び出しでオーバーロードの解決を実行するとき、候補の中からより適切な関数メンバーが存在する場合はそれを選択します。より良い関数メンバーの定義には、C# 言語仕様の §7.5.3.2 に次の文章が含まれています。

7.5.3.2 より良い機能メンバー

[...]

一連の引数式 { E1, E2, ..., EN } を持つ引数リスト A と、パラメーター型 { P1, P2, ..., PN } および { Q1, Q2 を持つ 2 つの適用可能な関数メンバー MP および MQ があるとします。 ..., QN }, 次の場合、MP は MQ よりも優れた関数メンバーとして定義されます。

  • 各引数について、EX から QX への暗黙的な変換は、EX から PX への暗黙的な変換よりも優れていません。
  • 少なくとも 1 つの引数について、EX から PX への変換は、EX から QX への変換よりも優れています。

[...]

この場合、MPが最初の方法 ( P1being int?) で、MQが 2 番目の方法 ( Q1being float?) です。nullしたがって、 からへの変換がへの変換よりint?優れていることを証明できれば、動作は簡単に説明できfloat?ます。

これは、§7.5.3.5 のルールによって決定されます。

7.5.3.5 より良い変換ターゲット

2 つの異なる型 T1 と T2 が与えられた場合、次の少なくとも 1 つが成り立つ場合、T1 は T2 よりも適切な変換ターゲットです。

  • T1 から T2 への暗黙の変換が存在し、T2 から T1 への暗黙の変換は存在しない

から への暗黙的な変換は存在しますが、からintへの暗黙的な変換 (参照)は存在しないため、2 つの型の間で選択する場合は、より適切な変換ターゲットになります。floatfloatintint

あなたの例では、これらの型の null 許容バージョンを扱っていますが、同じロジックが適用されるため、

6.1.4 暗黙の null 許容変換

null 非許容値型で動作する定義済みの暗黙的な変換は、それらの型の null 許容形式でも使用できます。

于 2013-05-15T23:08:43.210 に答える