我一直在寻找的源代码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>;
结果为非null值并且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
值,并认为它可以在int
s列表上使用。在这些情况下,优化将使程序员受益(尽管不如了解值/引用类型那么多)。
我从乔恩·斯基特(Jon Skeet)的博客中得到了这个主意
只有Microsoft的实现该方法的人员才能确定地告诉您为什么如此执行。然而…
重要的是要注意,您提出的替代方案在很多有趣的情况下都行不通。与OfType<T>()
可能被调用的场景相比,它在什么时候可以工作非常有限。
实际上,它仅在呼叫者不应该首先呼叫的情况下起作用OfType<T>()
。毕竟,如果对象实际上已经是type IEnumerable<TResult>
,则按类型过滤源毫无意义。调用者应该已经足够了解源的实际类型,以了解是否确实需要这种过滤。而且,他们当然不应该呼吁OfType<T>()
消除null
价值的副作用。
那么,为什么要引入一个“优化”来只优化那些本来就不应该编写的代码呢?这几乎与通常的优化准则背道而驰。第一个规则是关注普通情况。优化不常见情况通常会浪费代码,尤其是在库中,并且在所讨论的不常见情况涉及不良代码时尤其如此。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句