C# コンパイラで何が起こって、次のあいまいな呼び出しコンパイル エラーが発生しますか?
同じ問題が拡張メソッドにも当てはまります。または、TestClass
がジェネリックであり、静的メソッドではなくインスタンスを使用している場合にも当てはまります。
解決するのはかなり簡単だと思いますが(メソッド呼び出しでキャストsecondInstance
するTest1
など)、メソッド選択のためにコンパイラによってどのロジックが適用されているのかもっと知りたいです。
私の仮定は、コンパイラがメソッド検出に特定レベルの特定尺度 (CSS など) を適用して、最も具体的な一致を判断することです。これは無効ですか?
class Type1 { }
class Type2 : Type1 {}
class TestClass
{
public static void Do<T>(T something, object o) where T : Type1
{}
public static void Do(Type1 something, string o)
{}
}
void Main()
{
var firstInstance = new Type1();
TestClass.Do(firstInstance, new object()); // Calls Do<T>(T, obj)
TestClass.Do(firstInstance, "Test"); // Calls Do(Type1, string)
var secondInstance = new Type2();
TestClass.Do(secondInstance, new object()); // Calls Do<T>(T, obj)
TestClass.Do(secondInstance, "Test"); // "The call is ambiguous" compile error
}
// 編集: mike z は、「キャスト距離」がメソッド選択の重みとして使用されていると私が解釈した概念を提案しました。これのテストはそれをサポートしているようです (ただし、Type->Generic Type がどのように重み付けされているかはわかりません)。
// Add the following two methods to TestClass
public static void Do<T>(T something) where T : Type1
{}
public static void Do(Type1 something)
{}
public static void Do<T>(T something, object o) where T : Type1
{}
public static void Do(Type1 something, string o)
{}
void Main()
{
var firstInstance = new Type1();
// Can't select string
TestClass.Do(firstInstance, new object()); // Calls Do<T>(T, obj)
// Do() distance is 0, Do<T> distance is 1
TestClass.Do(firstInstance, "Test"); // Calls Do(Type1, string)
// Do() distance is 0, Do<T> distance is ? (but more than 0?)
TestClass.Do(firstInstance); // Calls Do(Type1)
var secondInstance = new Type2();
// Can't select string
TestClass.Do(secondInstance, new object()); // Calls Do<T>(T, obj)
// Do() distance is 1, Do<T> distance is 1
TestClass.Do(secondInstance, "Test"); // "The call is ambiguous" compile error
// Do() distance is 1, Do<T> distance is ? (but less than 1?)
TestClass.Do(secondInstance); // Calls Do<T>(T)
}