C# コンパイラのあいまいな呼び出しエラー: 匿名メソッドとメソッド グループ
C# には、関数を呼び出すための 2 つの構文、匿名メソッド (またはラムダ構文) とメソッド グループが用意されています。関数に異なるデリゲート型を受け入れる複数のオーバーロードがある場合、メソッド グループ構文を使用するとあいまいさが発生する可能性があります。
次のコード例を考えてみましょう:
<code class="language-csharp">class Program { public static void Main() { // 匿名方法(编译成功) Method(() => classWithSimpleMethods.GetString()); Method(() => classWithSimpleMethods.DoNothing()); // 使用显式转换的方法组(也编译成功) Method((Func<string>)classWithSimpleMethods.GetString); Method((Action)classWithSimpleMethods.DoNothing); // 方法组(错误:“歧义调用”) Method(classWithSimpleMethods.GetString); Method(classWithSimpleMethods.DoNothing); } public static void Method(Func<string> func) { /* 执行某些操作 */ } public static void Method(Action action) { /* 执行某些操作 */ } }</code>
この例では、Method
関数には 2 つのオーバーロードがあり、1 つは Action
を受け入れ、もう 1 つは Func<string>
を受け入れます。匿名メソッドまたは正しいデリゲート型への明示的なキャストを使用して関数が呼び出された場合、コードはエラーなしでコンパイルされます。ただし、メソッド グループ構文を使用すると、コンパイラは「あいまいな呼び出し」エラーを報告します。
曖昧さを理解する
C# 言語仕様では、メソッド グループから互換性のあるデリゲート型への暗黙的な変換があると規定されています。ただし、この場合、メソッド グループ classWithSimpleMethods.GetString
が暗黙的に Func<string>
および Action
に変換される可能性があるため、コンパイラーはあいまいさに直面します。
仕様によれば、オーバーロードの解決には、一致する引数の型に基づいて最も適切な候補を選択することが含まれます。 GetString
メソッドのパラメーター リストは両方のオーバーロードと互換性がありますが、コンパイラーはオーバーロードの解決時に戻り値の型を考慮しないため、最も一致するものを決定できません。
曖昧さの解決
あいまいさを解決するには、コード例に示すように、正しいデリゲート型への明示的なキャストを使用できます。ただし、このアプローチは退屈でエラーが発生しやすい可能性があります。
幸いなことに、C# 7.3 以降では、コンパイラがこの状況に対処できるように改良されています。オーバーロードの候補は、ターゲットのデリゲート型との互換性に基づいてランク付けされるようになり、この場合の明示的な変換の必要がなくなります。
以上が匿名メソッドではなくメソッド グループを使用すると、C# が「あいまいな呼び出し」エラーをスローするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。