Я недавно написал это и был удивлен, что он компилируется:
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›', потому что они могут унифицироваться для некоторых замен параметров типа.
А почему первым разрешено писать?