我的对象是:
IQueryable<Foo>
我希望将它传递给一个需要:
的函数IQueryable<IFoo>
Foo DOES实施IFoo
为什么不编译?转换成这项工作的最佳方式是什么?
答案 0 :(得分:5)
在.NET 4 BCL中添加了协调和反对方差,并且在.NET 3.5 BCL中不存在。
您可以使用Select
操作强制转换为接口类型,从而解决3.5中的此限制:
IQueryable<Foo> foos = ..;
myFunc(foos.Select(x => (IFoo)x));
编辑(来自Reed的评论,见下文):
IQueryable<Foo> foos = ..;
myFunc(foos.Cast<IFoo>());
答案 1 :(得分:2)
除Stephen Cleary的答案外,您还可以使用OfType表达式:
IQueryable<Foo> foos = GetFoos();
var ifoos = foos.OfType<IFoo>();
我认为 OfType
方法可能会快一些,因为表达式是按类型过滤集合而不是强制转换。
Anthony Pegram在评论中提出了一个很好的观察/观点。以下是对1,000,000件商品的OfType<>
与Cast<>
的快速测试:
OfType Test
00:00:00.1034880
00:00:00.0966734
00:00:00.0969874
00:00:00.1318617
00:00:00.0984404
00:00:00.0970098
00:00:00.0981691
00:00:00.0972425
00:00:00.1330730
00:00:00.1239663
total: 00:00:01.0769116
avg: 00:00:00.1076911
Cast Test
00:00:00.0556266
00:00:00.0729768
00:00:00.0512704
00:00:00.0519060
00:00:00.0533288
00:00:00.0752939
00:00:00.0754975
00:00:00.0821554
00:00:00.0536814
00:00:00.0754732
total: 00:00:00.6472100
avg: 00:00:00.0647210
答案 2 :(得分:1)
这不起作用的原因是因为List<Foo>
是一个正在生成的新类,所以List<IFoo>
...所以,当编译器完成它们时,它们现在就会生效在你的项目中成为2个全新且独特的课程。
编辑:一种解决方案:
你可以做的是:
var myIFooList = myFooList.Select(item => (IFoo)item).ToList();