何时在Linq中使用Cast()和Oftype()

205 .net c# linq

我知道有两种方法可以IEnumerableArraylistLinq中输出类型,并想知道在哪些情况下使用它们?

例如

IEnumerable<string> someCollection = arrayList.OfType<string>()
Run Code Online (Sandbox Code Playgroud)

要么

IEnumerable<string> someCollection = arrayList.Cast<string>()
Run Code Online (Sandbox Code Playgroud)

这两种方法有什么区别,我应该在哪里应用每种情况?

Ita*_*aro 313

OfType - 仅返回可以安全地转换为x类型的元素.
Cast - 将尝试将所有元素转换为x类型.如果其中一些不属于这种类型,你会得到InvalidCastException

编辑
例如:

object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }
Run Code Online (Sandbox Code Playgroud)

  • 即使在`.Cast <string>()`在枚举时不抛出的情况下,它**也不等于`.OfType <string>()`.原因是`.OfType <TResult>()`总是跳过**`null`值**.例如:`new System.Collections.ArrayList {"abc","def",null,"ghi",}.OfType <string>().Count()`只给出`3`; `.Cast <string>()`的类似表达式计算结果为'4`. (22认同)
  • @SLaks正确地指出,当你确定集合只包含类型`T`元素时,你应该使用`Cast <T>`.`OfType <T>`由于`is`类型检查而变慢.如果集合的类型为`IEnumerable <T>`,那么`Cast <T>`将简单地将整个集合强制转换为`IEnumerable <T>`并避免枚举它; `OfType <T>`仍然会枚举.参考:http://stackoverflow.com/questions/11430570/why-is-oftype-faster-than-cast (6认同)
  • 换句话说,就像“as”和“cast”运算符之间的区别 (2认同)

Ash*_*Ash 105

http://solutionizing.net/2009/01/18/linq-tip-enumerable-oftype/

从根本上说,Cast()实现如下:

public IEnumerable<T> Cast<T>(this IEnumerable source)
{
  foreach(object o in source)
    yield return (T) o;
}
Run Code Online (Sandbox Code Playgroud)

使用显式强制转换可以很好地执行,但如果强制转换失败,则会导致InvalidCastException.OfType()的一个效率较低但有用的变化是OfType():

public IEnumerable<T> OfType<T>(this IEnumerable source)
{
  foreach(object o in source)
    if(o is T)
      yield return (T) o;
}
Run Code Online (Sandbox Code Playgroud)

返回的枚举将只包含可以安全地转换为指定类型的元素.


SLa*_*aks 36

Cast<string>()如果您知道所有项目都是strings ,您应该打电话.
如果其中一些不是字符串,你会得到一个例外.

OfType<string>()如果您知道某些物品不是strings并且您不想要这些物品,则应该打电话.
如果它们中的一些不是字符串,它们将不属于新字符串IEnumerable<string>.

  • 请注意,“OfType&lt;string&gt;()”也会跳过“null”值。例如: `new string[] { "abc", "123", null, "" }.OfType&lt;string&gt;().Count()` 等于 `3`,而 `.Cast&lt;string&gt;().Count( )` 等于 `4`。 (4认同)
  • 这个答案是(目前)唯一给出明确建议何时使用哪种方法的答案。 (2认同)

小智 7

应该注意的是,Cast(Of T)可以在IEnumerable与其他 LINQ 函数不同的地方使用LINQ,因此,如果您需要在非泛型集合或列表(例如 )上使用 LINQ ArrayList,则可以使用Cast(Of T)强制转换为IEnumerable(Of T)LINQ 可以工作的位置。