何时在 Linq 中使用 Cast() 和 Oftype()
Posted
技术标签:
【中文标题】何时在 Linq 中使用 Cast() 和 Oftype()【英文标题】:When to use Cast() and Oftype() in Linq 【发布时间】:2010-10-25 15:09:15 【问题描述】:我知道在 Linq 中将类型转换为 IEnumerable
的两种方法从 Arraylist
并想知道在哪些情况下使用它们?
例如
IEnumerable<string> someCollection = arrayList.OfType<string>()
或
IEnumerable<string> someCollection = arrayList.Cast<string>()
这两种方法有什么区别,我应该在哪里应用每种情况?
【问题讨论】:
【参考方案1】:OfType
- 仅返回可以安全地转换为类型 x 的元素。Cast
- 将尝试将所有元素转换为类型 x。如果其中一些不是这种类型,你会得到InvalidCastException
编辑 例如:
object[] objs = new object[] "12345", 12 ;
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return "12345"
【讨论】:
为此欢呼。事先都尝试过,但两者都有预期的所有类型的元素,因此我看不到差异。 @SLaks 正确地指出,当您确定集合仅包含T
类型元素时,您应该使用 Cast<T>
。由于is
类型检查,OfType<T>
速度较慢。如果集合是IEnumerable<T>
类型,Cast<T>
将简单地将整个集合转换为IEnumerable<T>
并避免枚举它; OfType<T>
仍将枚举。参考:***.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
。
换句话说,有点像'as'和'cast'操作符的区别【参考方案2】:
来源: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)
yield return (T) o;
返回的枚举将只包括可以安全地转换为指定类型的元素。
【讨论】:
【参考方案3】:如果您知道所有项目都是string
s,则应致电Cast<string>()
。
如果其中一些不是字符串,你会得到一个异常。
如果您知道某些项目不是 string
s 并且您不想要这些项目,您应该致电 OfType<string>()
。
如果其中一些不是字符串,它们将不会出现在新的 IEnumerable<string>
中。
【讨论】:
这个答案是(目前)唯一一个明确建议何时使用哪种方法的答案。 请注意,OfType<string>()
也将跳过 null
值。例如:new string[] "abc", "123", null, "" .OfType<string>().Count()
等于 3
,而 .Cast<string>().Count()
将等于 4
。【参考方案4】:
需要注意的是,Cast(Of T)
可以在 IEnumerable
上使用,这与其他 LINQ 函数不同,因此,如果您需要在非泛型集合或列表(例如 ArrayList
)上使用 LINQ,您可以使用 Cast(Of T)
转换为 LINQ 可以工作的 IEnumerable(Of T)
。
【讨论】:
【参考方案5】:Cast()
将尝试转换集合中的所有元素(如果元素类型错误,则会抛出异常),而OfType()
将仅返回正确类型的元素。
【讨论】:
【参考方案6】:OfType
将过滤元素以仅返回指定类型的元素。
Cast
会在一个元素不能被转换为目标类型时崩溃。
【讨论】:
【参考方案7】:Cast<T>
将尝试将所有项目转换为给定类型T
。此转换可能会失败或引发异常。 OfType<T>
将返回原始集合的子集,并且只返回 T
类型的对象。
【讨论】:
以上是关于何时在 Linq 中使用 Cast() 和 Oftype()的主要内容,如果未能解决你的问题,请参考以下文章
何时使用 .First 以及何时将 .FirstOrDefault 与 LINQ 一起使用?
LINQ:何时使用SingleOrDefault与FirstOrDefault()一起使用过滤条件
linq中AsEnumerable和AsQueryable的区别