【发布时间】:2019-12-01 02:09:11
【问题描述】:
我在看System.Linq.Enumerable.OfType<TResult>()的源代码:
public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source) {
if (source == null) throw Error.ArgumentNull("source");
return OfTypeIterator<TResult>(source);
}
static IEnumerable<TResult> OfTypeIterator<TResult>(IEnumerable source) {
foreach (object obj in source) {
if (obj is TResult) yield return (TResult)obj;
}
}
如果IEnumerable<TResult> typedSource = source as IEnumerable<TResult>; 产生非空值,而TResult 是值类型,则不能有任何null 值,因此无需枚举每个值。
您可以将源返回为IEnumerable<TResult>
他们有什么理由不设计这样的方法吗?:
public static IEnumerable<TResult> OfType<TResult>(this IEnumerable source)
{
if (source == null) throw new ArgumentNullException("source");
IEnumerable<TResult> typedSource = source as IEnumerable<TResult>;
if (typedSource != null)
{
if (typeof(TResult).IsValueType)
{
return typedSource;
}
}
return OfTypeIterator<TResult>(source);
}
如果源包含大量元素,只需检查源是否仅包含值类型,就可以节省大量时间。
编辑:
我知道一些初学者还没有了解值/引用类型,也不知道值类型不能是null。
我可以想象初学者开发人员会知道OfType<T>() 过滤掉null 值的情况,认为它可以在ints 列表上工作。
在这些情况下,优化将使程序员受益(尽管不如学习值/引用类型那么多)。
我的想法来自Jon Skeet's blog
【问题讨论】:
-
我在这里可能是错的,但这可能有用的唯一地方是当 T(源)== TResult 时。如果 TResult 是 ValueType 并且与 T 相同,为什么要使用 OfType ?不确定,这将如何实际优化 OfType 方法
-
你从哪里得到这个实现?我记得不同的框架有不同的实现。例如 .Net Core 和 .NET 框架之间的不同
-
@M.kazemAkhgary 这是来自 GitHub 的源代码。
-
@AnuViswan:您可能在编译时不知道源代码的
T。不要忘记这个(和Cast)的目标是IEnumerable,而不是IEnumerable<T>。Cast方法是这样优化的。 -
请注意,这在
TResult是可空值类型的情况下不起作用 - 真正的OfType方法也会从中过滤掉空值。不过你可以很容易地解决这个问题。
标签: c# .net ienumerable