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

我知道在Linq中有两种方法将类型从Arraylist转换为IEnumerable,不知道在哪些情况下使用它们?

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

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

这两种方法之间的区别是什么?我应该在哪里应用每种情况?

100412 次浏览

OfType -只返回可以安全转换为类型x的元素 Cast -将尝试将所有元素转换为x类型。如果其中一些元素不属于此类型,则将得到InvalidCastException

< p > 编辑 < br > 例如:< / p >
object[] objs = new object[] { "12345", 12 };
objs.Cast<string>().ToArray(); //throws InvalidCastException
objs.OfType<string>().ToArray(); //return { "12345" }

Cast()将尝试强制转换集合的所有元素(如果元素类型错误,将抛出异常),而OfType()将只返回正确类型的元素。

来源:LINQ提示:可枚举的。OfType -解决。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;
}

返回的枚举将只包括可以安全地转换为指定类型的元素。

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

如果你知道所有的项都是__abc1,你应该调用Cast<string>() 如果其中一些不是字符串,你将得到一个异常 如果你知道某些项不是__abc1,并且你不想要这些项,你应该调用OfType<string>() 如果其中一些不是字符串,则它们将不在新的IEnumerable<string>

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

需要注意的是,与其他LINQ函数不同,Cast(Of T)可以在IEnumerable上使用,因此如果有需要在非泛型集合或列表(如ArrayList)上使用LINQ的情况,则可以使用Cast(Of T)转换为LINQ可以工作的IEnumerable(Of T)