And*_*eas 6 c# generics ambiguity
我最近写了这篇文章并且惊讶于它编译:
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>',因为它们可能会统一某些类型参数替换
为什么第一个允许写?
1-为什么以下内容不允许编译?
部分回复在那篇文章中:为什么 C# 编译器抱怨“类型可能统一”,当它们派生自不同的基类时?
C# 4 规范的第 13.4.2 节指出:
由泛型类型声明实现的接口对于所有可能的构造类型必须保持唯一。如果没有这条规则,就不可能确定调用某些构造类型的正确方法。
2- 为什么第一个被允许写?
编译器在编译时执行泛型类型检查,C# 4 规范第 7.4.3.5 节指出:
虽然声明的签名必须是唯一的,但类型参数的替换可能会产生相同的签名。在这种情况下,上面的重载解析的平局规则将选择最具体的成员。以下示例显示根据此规则有效和无效的重载:
interface I1<T> {...}
interface I2<T> {...}
class G1<U>
{
    int F1(U u);                    // Overload resulotion for G<int>.F1
    int F1(int i);                  // will pick non-generic
    void F2(I1<U> a);               // Valid overload
    void F2(I2<U> a);
}
class G2<U,V>
{
    void F3(U u, V v);          // Valid, but overload resolution for
    void F3(V v, U u);          // G2<int,int>.F3 will fail
    void F4(U u, I1<V> v);      // Valid, but overload resolution for   
   void F4(I1<V> v, U u);       // G2<I1<int>,int>.F4 will fail
    void F5(U u1, I1<V> v2);    // Valid overload
    void F5(V v1, U u2);
    void F6(ref U u);               // valid overload
    void F6(out V v);
}
| 归档时间: | 
 | 
| 查看次数: | 330 次 | 
| 最近记录: |