When to use Cast() and Oftype() in Linq
我知道两种从LINQ中的Arraylist向IEnumerable投射类型的方法,我想知道在哪种情况下使用它们?
例如
1
| IEnumerable<string> someCollection = arrayList.OfType<string>() |
或
1
| IEnumerable<string> someCollection = arrayList.Cast<string>() |
这两种方法的区别是什么?我应该在哪里应用每种情况?
OfType—只返回可以安全地强制转换为类型x的元素。Cast将尝试将所有元素强制转换为类型x。如果其中一些元素不是此类型的元素,您将得到InvalidCastException。
编辑例如:
1 2 3
| object[] objs = new object[] {"12345", 12 };
objs .Cast<string>().ToArray(); //throws InvalidCastException
objs .OfType<string>().ToArray(); //return {"12345" } |
- 为此干杯。之前都试过了,但都有预期类型的元素,所以我看不出有什么不同。
- @Slaks正确地指出,当您确信集合只包含类型T元素时,应该使用Cast。由于is类型检查,OfType速度较慢。如果集合是IEnumerable类型,Cast只将整个集合强制转换为IEnumerable并避免枚举;OfType仍将枚举。参考:stackoverflow.com/questions/11430570/&hellip;
- 即使在枚举时.Cast()不抛出的情况下,它也不等于.OfType()。原因是.OfType()总是跳过null值。例如:new System.Collections.ArrayList {"abc","def", null,"ghi", }.OfType().Count()只给出3;与.Cast()相似的表达式计算为4。
- 换句话说,它类似于"as"和"cast"运算符之间的区别。
http://solutionioning.net/2009/01/18/linq-tip-enumerable-of类型/
从根本上讲,cast()的实现方式如下:
1 2 3 4 5
| public IEnumerable<T> Cast<T>(this IEnumerable source)
{
foreach(object o in source)
yield return (T) o;
} |
使用显式强制转换效果很好,但如果强制转换失败,将导致InvalidCastException。这个想法的一个效率较低但有用的变体是oftype():
1 2 3 4 5 6
| public IEnumerable <T > OfType <T >(this IEnumerable source )
{
foreach(object o in source )
if(o is T )
yield return (T ) o ;
} |
返回的枚举将只包含可以安全地强制转换为指定类型的元素。
如果你知道所有的物品都是string,你应该打电话给Cast()。如果其中一些不是字符串,您将得到一个异常。
如果你知道有些物品不是string,而且你不想要这些物品,你应该打电话给OfType()。如果其中一些不是字符串,它们就不会出现在新的IEnumerable中。
- 这个答案是(目前)唯一给出明确建议何时使用哪个方法的答案。
需要注意的是,与其他Linq函数不同,Cast(Of T)可用于IEnumerable,因此,如果有需要在非通用集合或列表(如ArrayList上使用Linq的情况,可以使用Cast(Of T)来强制转换到Linq可以工作的IEnumerable(Of T)上。
Cast将尝试将所有项目强制转换为给定的T类型。此强制转换可能失败或引发异常。OfType将返回原始集合的一个子集,只返回T类型的对象。
OfType将过滤元素,只返回指定类型的元素。如果元素不能强制转换为目标类型,则Cast将崩溃。
Cast()将尝试强制转换集合的所有元素(如果元素的类型错误,则抛出异常),而OfType()将只返回正确类型的元素。