通用约束忽略协方差
Generic constraint ignores co-variance
假设我们有一个像
这样的界面
public interface IEnumerable<out T>
{ /*...*/ }
即 协变 in T
.
然后我们有另一个接口和一个 class 实现它:
public interface ISomeInterface {}
public class SomeClass : ISomeInterface
{}
现在,协方差允许我们执行以下操作
IEnumerable<ISomeInterface> e = Enumerable.Empty<SomeClass>();
因此 IEnumerable<SomeClass>
可分配 到 IEnumerable<ISomeInterface>
.
类型的变量(或方法参数)
但是如果我们在通用方法中尝试这个:
public void GenericMethod<T>(IEnumerable<T> p) where T : ISomeInterface
{
IEnumerable<ISomeInterface> e = p;
// or
TestMethod(p);
}
public void TestMethod(IEnumerable<ISomeInterface> x) {}
我们收到 编译器错误 CS0266 告诉我们 IEnumerable<T>
无法转换为 IEnumerable<ISomeInterface>
。
约束明确指出 T
派生自 ISomeInterface
,并且由于 IEnumerable<T>
在 T
中是协变的,因此该赋值应该有效(如上所示).
这在通用方法中不起作用是否有任何技术原因?或者我遗漏的任何东西使得编译器无法解决它的成本太高?
更改您的 GenericMethod
并添加通用约束 class
:
public void GenericMethod<T>(IEnumerable<T> p) where T : class, ISomeInterface
{
IEnumerable<ISomeInterface> e = p;
// or
TestMethod(p);
}
Covariance does not support structs,所以我们需要说明我们只想使用类。
假设我们有一个像
这样的界面public interface IEnumerable<out T>
{ /*...*/ }
即 协变 in T
.
然后我们有另一个接口和一个 class 实现它:
public interface ISomeInterface {}
public class SomeClass : ISomeInterface
{}
现在,协方差允许我们执行以下操作
IEnumerable<ISomeInterface> e = Enumerable.Empty<SomeClass>();
因此 IEnumerable<SomeClass>
可分配 到 IEnumerable<ISomeInterface>
.
但是如果我们在通用方法中尝试这个:
public void GenericMethod<T>(IEnumerable<T> p) where T : ISomeInterface
{
IEnumerable<ISomeInterface> e = p;
// or
TestMethod(p);
}
public void TestMethod(IEnumerable<ISomeInterface> x) {}
我们收到 编译器错误 CS0266 告诉我们 IEnumerable<T>
无法转换为 IEnumerable<ISomeInterface>
。
约束明确指出 T
派生自 ISomeInterface
,并且由于 IEnumerable<T>
在 T
中是协变的,因此该赋值应该有效(如上所示).
这在通用方法中不起作用是否有任何技术原因?或者我遗漏的任何东西使得编译器无法解决它的成本太高?
更改您的 GenericMethod
并添加通用约束 class
:
public void GenericMethod<T>(IEnumerable<T> p) where T : class, ISomeInterface
{
IEnumerable<ISomeInterface> e = p;
// or
TestMethod(p);
}
Covariance does not support structs,所以我们需要说明我们只想使用类。