如果对象实现了该接口,我可以将IQueryable <foo>传递给IQueryable <ifoo>吗?</ifoo> </foo>

时间:2011-02-09 02:08:59

标签: c# .net-3.5

我的对象是:

IQueryable<Foo>

我希望将它传递给一个需要:

的函数
IQueryable<IFoo>

Foo DOES实施IFoo

为什么不编译?转换成这项工作的最佳方式是什么?

3 个答案:

答案 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();