Answers:
OfType
-仅返回可以安全转换为x类型的元素。
Cast
-将尝试将所有元素转换为x类型。如果其中一些不是这种类型的,您将得到InvalidCastException
编辑
例如:
object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }
Cast<T>
在确定集合仅包含类型T
元素时应使用的名称。OfType<T>
由于is
类型检查而变慢。如果collection是type IEnumerable<T>
,Cast<T>
将简单地将整个collection转换为,IEnumerable<T>
并避免枚举;OfType<T>
仍会枚举。REF: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
。
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;
}
返回的枚举将仅包含可以安全地强制转换为指定类型的元素。
Cast()
会尝试强制转换集合的所有元素(如果element的类型错误,则会抛出异常),而OfType()
只会返回正确类型的元素。