![](/img/trans.png)
[英]Why can't I pass a List<List<Foo>> to an IEnumerable<IEnumerable<Foo>>
[英]Why can't I pass IList<ChildType> to F(IEnumerable<ParentType>)?
我想我可以将IList<ChildClass>
作为IEnumerable<ParentClass>
传递,因为显然 ChildType 列表中的每个 object 也是 ParentType 的实例。 但我对编译器没有兴趣。 我错过了什么?
编辑:添加了我想要的 function Foo3 。 谢谢!
namespace StackOverflow
{
public class ParentClass
{
}
public class ChildClass : ParentClass
{
}
public class Test
{
// works
static void Foo(ParentClass bar2)
{
}
// fails
static void Foo2(IEnumerable<ParentClass> bar)
{
}
// EDIT: here's the right answer, obtained from the
// Charlie Calvert blog post
static void Foo3<T>(IEnumerable<T> bar) where T : ParentClass
{
}
public static void Main()
{
var childClassList = new List<ChildClass>();
// this works as expected
foreach (var obj in childClassList)
Foo(obj);
// this won't compile
// Argument '1': cannot convert from
// 'System.Collections.Generic.List<ChildClass>'
// to 'System.Collections.Generic.IEnumerable<ParentClass>'
Foo2(childClassList);
// EDIT: this works and is what I wanted
Foo3(childClassList);
}
}
}
您缺少通用方差,目前 C#中不存在该方差。 我相信您的代码可以在 C# 4.0 中运行。
虽然这是其他问题的重复...
看:
您应该在Eric Lippert 的 Covariance and Contravariance 系列中找到您要查找的所有内容。 这是一个相当多的阅读,但回答了(a)为什么你不能在 C# 3.0 中做到这一点,以及(b)为什么你能够在 C# 4.0 中做到这一点。
恐怕没有对泛型参数类型的隐式转换(没有“泛型方差”似乎是技术术语)。 不确定我能否给你更深入的解释,但我会接受它作为 CLR 的工作方式......
您只需使用 childClassList 上的Cast扩展方法将列表转换为 IEnumerable。
虽然在 IList 和 IEnumerable 的情况下一切正常,但当您将其视为集合和集合时,编译器无法真正知道这一点。
如果您可以将集合用作集合,则有人可以尝试将 Parent 添加到集合中……编译器必须防止这种情况发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.