IEnumerable 的 C# 通用约束

标签 c# generics

public interface I {
}
public class A : I {
}

编译器采用显式 IEnumerable<A>作为IEnumerable<I> :

public void Test() {
    IEnumerable<A> a = new List<A>();
    new List<I>().AddRange(a);
}

但是有了通用约束,我们得到:

public void Test<T>() where T : I {
    IEnumerable<T> t = new List<T>();
    new List<I>().AddRange(t);
}
                          ^^^
Argument 1: cannot convert from 'IEnumerable<T>' to 'IEnumerable<I>'

但是,这可以正常编译。

public void Test<T>(T t) where T : I {
    new List<I>().Add(t);
}

因此问题来了:这是正确的行为还是错误?

最佳答案

问题是泛型协变只适用于引用类型。例如,List<int>不是* IEnumerable<Comparable> ,而是一个 List<string>是。

所以如果你限制T作为引用类型,它编译:

public void Foo<T, I>() where T : class, I 
{
    IEnumerable<T> t = new List<T>();
    new List<I>().AddRange(t);
}

关于IEnumerable 的 C# 通用约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11630676/

相关文章:

接口(interface)的泛型、通配符和 super /扩展

delphi - 是否有实现 QueryInterface 的泛型类型?

c# - 我可以使用通用约束来启用参数化构造函数吗?

c# - 在代码中放置密码的方法

c# - Console.Read() 和 Console.ReadLine() 之间的区别?

c# - 使用 LINQ 转换投影列表返回空值列表?

映射后的Java流到数组

c# - 解析大双值C#

c# - 通过委托(delegate)生成接口(interface)实现的工具?

Java 使二叉搜索树通用(它有效,但我知道我做得不对)