OfType ()与Where()扩展中的检查类型之间的区别
除了可读性之外,以下linq查询之间的区别是什么,以及何时以及为什么我将使用其中一个:
IEnumerable items = listOfItems.Where(d => d is T).Cast();
和
IEnumerable items = listOfItems.OfType();
更新: Dang,抱歉在尝试简化我的问题时介绍了一些错误
让我们比较三种方法(注意generics参数):
-
在
IEnumerable
上调用的listOfItems.Where(t => t is T)
仍将返回仅被过滤的IEnumerable
以仅包含类型T
元素。 -
在
IEnumerable
上调用的listOfItems.OfType
将返回包含可以转换为类型() T
元素的IEnumerable
。 -
在
IEnumerable
上调用的listOfItems.Cast
将返回() IEnumerable
其中包含已转换为类型T
元素,或者如果无法转换任何元素则抛出exception。
和listOfItems.Where(d => d is T).Cast
基本上做了两次相同的事情 – Where
过滤所有T
元素,但仍然留下类型IEnumerable
然后再次尝试Cast
转换他们到T
但这次返回IEumerable
。
如果我对你的例子采取一些自由并在LINQPad中进行调整,这就是我得到的:
方法
List GetNumbers (List nums){ return nums.Where(d => d is T).ToList (); } List GetNumbersOfType (List nums){ return nums.OfType ().ToList (); }
IL
GetNumbers: IL_0000: ldarg.1 IL_0001: ldnull IL_0002: ldftn 05 00 00 2B IL_0008: newobj 0A 00 00 0A IL_000D: call 06 00 00 2B IL_0012: call 07 00 00 2B IL_0017: ret GetNumbersOfType: IL_0000: ldarg.1 IL_0001: call 08 00 00 2B IL_0006: call 07 00 00 2B IL_000B: ret
我不是IL专家,但它看起来像GetNumbers
方法(使用Where
语法)每次通过循环创建一个新对象,因此可能比GetNumbersOfType
方法(使用OfType
)消耗更多的内存。
listOfItems.Where(d => d is T)
返回IEnumerable
(其中U是listOfItems中项目的类型),仅包含类型为T的项目。
listOfItems.OfType
返回IEnumerable
。
实质上,编译代码的编译运行时配置文件没有区别。 OfTypeIterator
OfType
返回一个OfTypeIterator
,它在内部执行一次测试,并yield return
匹配的yield return
。