通用约束忽略协方差

时间:2017-09-27 14:52:39

标签: c# generics covariance

假设我们有一个像

这样的界面
public interface IEnumerable<out T>
{ /*...*/ }

T中的共同变体

然后我们有另一个接口和一个实现它的类:

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中的共变体,因此此分配应该有效(如上所示)。

是否有任何技术原因导致这种方法无法在通用方法中起作用?或者我错过的任何东西都会让编译器弄清楚它的成本太高了?

1 个答案:

答案 0 :(得分:5)

更改您的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,所以我们需要告诉我们只想使用类。