私は最近これを書きました、そしてそれがコンパイルすることに驚いていました:
public class MyGeneric<U, V> {
MyGeneric(U u) { ... }
MyGeneric(V v) { ... }
public void Add(U u, V v) { ... }
public void Add(V v, U u) { ... }
}
このクラスを次のように使用すると、Addを呼び出すと、「あいまいなコンストラクター参照」と「あいまいな呼び出し」が得られます。
var myVar = new MyGeneric<int, int>(new MyIntComparer());
明らかに、intとdoubleをジェネリック型として使用する場合、もちろん両方のintを使用する場合を除いて、あいまいさはありません。両方ともdoubleに割り当てられます。
var myVar = new MyGeneric<int, double>(new MyIntComparer());
myVar.Add(3, 5);
それで、以下も許されると思いましたが、意外とエラーになりました。以下のコンパイルが許可されていないのはなぜですか?
public interface IMyInterface<T, S> {
void Add(T t, S s);
}
public class MyGeneric<U, V> : IMyInterface<U, V>, IMyInterface<V, U> {
public MyGeneric(U u) { }
public MyGeneric(V v) { }
void IMyInterface<U, V>.Add(U u, V v) { ... }
void IMyInterface<V, U>.Add(V v, U u) { ... }
}
暗黙的または明示的なインターフェイス実装を使用するかどうかに関係なく、コンパイラは次のように述べています。
「MyGeneric<U、V>」は、「IMyInterface <U、V>」と「IMyInterface <V、U>」の両方を実装できません。これらは、一部のタイプパラメータ置換で統合される可能性があるためです。
そして、なぜ最初に書くことが許されているのですか?