我偶然发现了一种情况,在这种情况下,自动类型演绎的.NET 4.0MS-C#编译器失败,我必须指定类型“手动”。
这对我来说不是什么大问题,但足以让我好奇为什么编译器不能自动为调用找到正确的类型。
我将调用减少到以下程序:
class Program
{
interface GenericInterface<T> { }
interface Covariant<out T> { }
static void Fn<T, U>(GenericInterface<T> t, U u)
where T : Covariant<U>
{
}
class Base { }
class Derived : Base { }
static void Main(string[] args)
{
Base b = null;
Derived d = null;
GenericInterface<Covariant<Base>> c = null;
Fn(c, b); // 1
Fn<Covariant<Base>, Base>(c, d); // 2
Fn(c, d); // 3
}
}代码没有编译,因为最后一次调用Complex,标记为"// 3“。
第一个调用是简单而直接的--不涉及基类/子类。第二个调用只指定所有参数“手动”。
我原以为编译器也会自动为第三个调用选择第二个调用中使用的参数。当然,第二个参数实际上是“派生”的,但这可以转换为"Base“,第一个参数需要U类型为"Base”。WHER-子句仍然可以使用"Base“作为U,因为接口中的协变类型。
我不知道C#中泛型类型参数推导的具体规则,但我总是假设,它的工作方式有点像“如果参数有一个可能的赋值,就使用这个。如果没有,拒绝编译。”
为什么编译器不自动检测类型?这其中的一个“如果一个编译器能够做到这一点,那么它也必须能够解决费马的最后定理”-案例?:D
发布于 2013-12-04 15:10:13
WHER-子句仍然可以使用"Base“作为U,因为接口中的协变类型。
我想这就是你出错的地方。编译器不认为泛型约束是方法签名的一部分。。
因此,我认为在第三种情况下可能发生的情况是编译器正在推断T = Covariant<Base>和U = Derived。然后继续检查T上的泛型约束,Covariant<Base>没有实现Covariant<Derived>,因此该约束不满足,编译失败。
https://stackoverflow.com/questions/20378702
复制相似问题