【问题标题】:Generic constraint ignores co-variance通用约束忽略协方差
【发布时间】:2017-09-27 14:52:38
【问题描述】:

假设我们有一个类似的界面

public interface IEnumerable<out T>
{ /*...*/ }

这是T中的协变体

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

public interface ISomeInterface {}
public class SomeClass : ISomeInterface
{}

现在协方差允许我们执行以下操作

IEnumerable<ISomeInterface> e = Enumerable.Empty<SomeClass>();

所以IEnumerable&lt;SomeClass&gt; 可分配IEnumerable&lt;ISomeInterface&gt; 类型的变量(或方法参数)。

但是如果我们在一个通用方法中尝试这个:

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&lt;T&gt; 转换为 IEnumerable&lt;ISomeInterface&gt;

约束清楚地表明T 是从ISomeInterface 派生的,并且由于IEnumerable&lt;T&gt;T 中是协变的,因此该分配应该有效(如上所示)。

是否有任何技术原因导致这不能在通用方法中工作?或者我错过了什么让编译器无法计算出来的成本太高?

【问题讨论】:

    标签: c# generics covariance


    【解决方案1】:

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

    【讨论】:

    • 哦,抢我一步。现在我记得几天前我读过一些关于结构/方差问题的东西。感谢您的快速回复。
    • @RenéVogt 很高兴为您提供帮助
    猜你喜欢
    • 2018-04-27
    • 2016-10-07
    • 2016-11-04
    • 2015-01-02
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    相关资源
    最近更新 更多