C# 我可以通过IQueryable<;Foo>;进入IQueryable<;IFoo>;如果对象实现了该接口?

C# 我可以通过IQueryable<;Foo>;进入IQueryable<;IFoo>;如果对象实现了该接口?,c#,.net-3.5,C#,.net 3.5,我有一个对象是: IQueryable<Foo> IQueryable 我想将其传递到一个函数中,该函数需要: IQueryable<IFoo> IQueryable Foo不实现IFoo 为什么这个不能编译?转换为具有此功能的最佳方法是什么?协方差和反方差被添加到.NET 4 BCL中,而在.NET 3.5 BCL中不存在 在3.5中,您可以通过使用Select操作来转换到您的界面类型,从而绕过此限制: IQueryable<Foo> foos =

我有一个对象是:

IQueryable<Foo>
IQueryable
我想将其传递到一个函数中,该函数需要:

IQueryable<IFoo>
IQueryable
Foo不实现IFoo


为什么这个不能编译?转换为具有此功能的最佳方法是什么?

协方差和反方差被添加到.NET 4 BCL中,而在.NET 3.5 BCL中不存在

在3.5中,您可以通过使用
Select
操作来转换到您的界面类型,从而绕过此限制:

IQueryable<Foo> foos = ..;
myFunc(foos.Select(x => (IFoo)x));
IQueryable-foos=。。;
myFunc(foos.Select(x=>(IFoo)x));
编辑(来自里德的评论,如下):

IQueryable-foos=。。;
myFunc(foos.Cast());

这不起作用的原因是,
List
是一个正在生成的新类,
List
。。。因此,当编译器使用它们时,它们现在将是项目中的两个全新且唯一的类

编辑:一种解决方案:

你能做的是:

var myIFooList = myFooList.Select(item => (IFoo)item).ToList();

除答案外,您还可以使用以下表达式:

IQueryable<Foo> foos = GetFoos();
var ifoos = foos.OfType<IFoo>();

嘿,现在你可以看到标签了,这个答案就更有意义了。在
列表
周围使用backtick
`
来提高内联代码的可读性,特别是当涉及泛型时。+1:我建议改为使用
foo.Cast()
,不过:…我不知道
IQueryable
有一个
Cast
!好提示<类型的代码>仍将强制转换为所需类型。如果(obj是TResult)收益率回报(TResult)obj,则将其视为
如果序列完全是
TResult
,则检查是多余的。将
Cast
简单地看作
收益率回报(TResult)obj你认为哪一个会更快?当源序列真正混合时,使用类型
。在不需要时使用
Cast
。在许多情况下使用
Cast
的另一个(也许更重要)原因是隐含的明确性。如果某件事情发生在你没有预料到的顺序中,那将是一个例外情况<类型为
的code>显然不会漏拍。你的程序正确吗?视情况而定。你是否期望序列中的所有内容都可以转换为给定的类型?@Anthony-很好的澄清和解释。意图是一个很好的观点,即,我是否希望对类型进行过滤?还是把一切都抛在脑后?
IQueryable<Foo> foos = GetFoos();
var ifoos = foos.OfType<IFoo>();
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