OfType
- 仅返回可以安全地转换为类型 x 的元素。
Cast
- 将尝试将所有元素转换为类型 x。如果其中一些不是这种类型,您将获得 InvalidCastException
编辑例如:
object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }
来源:LINQ Tip: Enumerable.OfType - Solutionizing .NET
从根本上说,Cast<T>()
是这样实现的:
public IEnumerable<T> Cast<T>(this IEnumerable source)
{
foreach(object o in source)
yield return (T) o;
}
使用显式强制转换效果很好,但如果强制转换失败将导致 InvalidCastException
。这个想法的一个效率较低但有用的变体是 OfType<T>()
:
public IEnumerable<T> OfType<T>(this IEnumerable source)
{
foreach(object o in source)
if(o is T t)
yield return t;
}
返回的枚举将仅包括可以安全地转换为指定类型的元素。
如果您知道所有项目都是 string
,则应调用 Cast<string>()
。
如果其中一些不是字符串,您将收到异常。
如果您知道某些项目不是 string
并且您不想要这些项目,则应调用 OfType<string>()
。
如果其中一些不是字符串,它们将不会出现在新的IEnumerable<string>
。
OfType<string>()
也会跳过 null
值。例如:new string[] { "abc", "123", null, "" }.OfType<string>().Count()
等于 3
,而 .Cast<string>().Count()
将等于 4
。
应该注意的是,与其他 LINQ 函数不同,Cast(Of T)
可以在 IEnumerable
上使用,因此如果您需要在非泛型集合或列表(例如 ArrayList
)上使用 LINQ,您可以使用Cast(Of T)
转换为 LINQ 可以工作的 IEnumerable(Of T)
。
Cast()
将尝试强制转换集合中的所有元素(如果元素类型错误,则会引发异常),而 OfType()
将仅返回正确类型的元素。
OfType
将过滤元素以仅返回指定类型的元素。如果无法将元素强制转换为目标类型,Cast
将崩溃。
Cast<T>
将尝试将所有项目转换为给定类型 T
。此转换可能会失败或引发异常。 OfType<T>
将返回原始集合的子集并仅返回 T
类型的对象。
T
元素时,您应该使用Cast<T>
。由于is
类型检查,OfType<T>
速度较慢。如果集合是IEnumerable<T>
类型,Cast<T>
将简单地将整个集合转换为IEnumerable<T>
并避免枚举它;OfType<T>
仍将枚举。参考:stackoverflow.com/questions/11430570/….Cast<string>()
不抛出的情况下,它不等同于.OfType<string>()
。原因是null
值 总是被.OfType<TResult>()
跳过。一个例子:new System.Collections.ArrayList { "abc", "def", null, "ghi", }.OfType<string>().Count()
将只给出3
;具有.Cast<string>()
的类似表达式的计算结果为4
。