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


211

我知道在Linq中将类型转换为IEnumerablefrom的两种方法,Arraylist并且想知道在哪种情况下使用它们?

例如

IEnumerable<string> someCollection = arrayList.OfType<string>()

要么

IEnumerable<string> someCollection = arrayList.Cast<string>()

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

Answers:


322

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

编辑
例如:

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

1
为此欢呼。事先都尝试过,但是都具有所有预期类型的​​元素,因此为什么我看不到区别。

6
@SLaks正确指出Cast<T>在确定集合仅包含类型T元素时应使用的名称。OfType<T>由于is类型检查而变慢。如果collection是type IEnumerable<T>Cast<T>将简单地将整个collection转换为,IEnumerable<T>并避免枚举;OfType<T>仍会枚举。REF:stackoverflow.com/questions/11430570/...
嬉皮士

23
即使在.Cast<string>()枚举时不抛出的情况下,它也不等于.OfType<string>()。原因是null总是被跳过.OfType<TResult>()。一个例子:new System.Collections.ArrayList { "abc", "def", null, "ghi", }.OfType<string>().Count()只会给出3; 与的类似表达式的.Cast<string>()计算结果为4
Jeppe Stig Nielsen 2013年

1
换句话说,这就像“ as”运算符和“ cast”运算符之间的区别
faza

111

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;
}

使用显式强制转换效果很好,但是如果强制转换失败,则会导致InvalidCastException。关于这个想法,效率较低但有用的变化是OfType():

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

返回的枚举将仅包含可以安全地强制转换为指定类型的元素。


38

Cast<string>()如果您知道所有项目都是strings ,则应致电。
如果其中一些不是字符串,则会出现异常。

OfType<string>()如果您知道某些物品不是string并且您不想要这些物品,则应该致电。
如果其中一些不是字符串,则不会使用新的IEnumerable<string>


1
该答案是(当前)唯一给出使用哪种方法的明确建议的答案。
CodeFox

4

应该注意的是,Cast(Of T)它可以用于IEnumerable其他LINQ函数,因此,在某些情况下,如果您需要在非通用集合或列表(例如)上使用LINQ ArrayList,则可以将Cast(Of T)其强制转换为IEnumerable(Of T)LINQ可以工作的位置。



2

OfType将过滤元素以仅返回指定类型的元素。 Cast如果元素不能转换为目标类型,将崩溃。


2

Cast<T>将尝试将所有项目转换为给定类型T。此强制转换可能失败或引发异常。OfType<T>将返回原始集合的子集,并且仅返回类型为的对象T

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.