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