OfType ()与Where()扩展中的检查类型之间的区别

除了可读性之外,以下linq查询之间的区别是什么,以及何时以及为什么我将使用其中一个:

IEnumerable items = listOfItems.Where(d => d is T).Cast(); 

 IEnumerable items = listOfItems.OfType(); 

更新: Dang,抱歉在尝试简化我的问题时介绍了一些错误

让我们比较三种方法(注意generics参数):

  1. IEnumerable上调用的listOfItems.Where(t => t is T)仍将返回仅被过滤的IEnumerable以仅包含类型T元素。

  2. IEnumerable上调用的listOfItems.OfType()将返回包含可以转换为类型T元素的IEnumerable

  3. 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