c# - 通用约束忽略协方差

标签 c# generics covariance

假设我们有这样一个界面

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

这是 T 中的协变 .

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

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

关于c# - 通用约束忽略协方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56428065/

相关文章:

C# 使用 fiddlercore 创建对 url 的自动响应

c# - 折叠 div 将显示信息

scala - Scala中的存在与协方差

c# - 是c#中闭包中使用其字段时被闭包捕获的对象

c# - 通用约束和继承

java - 传递一个类参数并返回该类的对象(java)

C++ Vector of template class, 多态性

numpy - 相关二维矢量场

scala - Scala列表和子类型

c# - 为什么 CancellationToken 与 CancellationTokenSource 是分开的?