【发布时间】:2013-12-05 16:32:10
【问题描述】:
IEnumerable<TSource> 的 public static TSource Last<TSource>(this IEnumerable<TSource> source) 扩展方法对 IList<TSource> 类型的源进行了优化,因此当它可以使用索引进入末尾时,它不会遍历整个序列。
IList<TSource> tSources = source as IList<TSource>;
if (tSources != null)
{
int count = tSources.Count;
if (count > 0)
{
return tSources[count - 1];
}
}
我稍微修改了代码,使其更易于阅读,但功能保持不变。
当public static TSource Last<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) 可以清楚地从序列末尾开始迭代时,为什么它不进行优化?
如果应该有与谓词匹配的东西并且它靠近序列的开头,那么我仍然需要迭代到最后。如果最后有匹配的东西,我不必重复更多,因为我是从最后开始的。
我希望这样的东西成为该方法的一部分。
IList<TSource> tSources = source as IList<TSource>;
if (tSources != null)
{
int count = tSources.Count;
if (count > 0)
{
for (int i = count - 1; i >= 0; i--)
{
if (predicate(tSources[i]))
{
return tSources[i];
}
}
}
}
【问题讨论】:
-
有许多优化是可以执行的。例如,
Reverse可以针对列表进行优化,但不是。与以往的任何其他功能一样,答案是要么他们没有想到该功能,要么他们认为不值得花时间实施。 -
难以置信。我使用 .NET 已经有几年了,我特别喜欢它,因为它们不会发布半生不熟的功能。我什至听过 C# 设计团队的某个人的采访,他甚至说了这句话。此外,当他们优化更多方法时,他们不能简单地忽略这一点。
-
所以你认为这个方法是半生不熟的,只是因为它没有这个功能?意识到像 C# 这样的语言有数以万计的提议特性需要被拒绝。只有很小一部分被考虑的功能可以实现。有 很多 被拒绝的功能实际上可能相当有用。团队根本没有无限的资源。
-
还要注意,这不仅会改变性能,还会改变方法的功能。如果谓词有副作用,您将更改哪些项目调用了谓词,以及调用的顺序。这可能是个问题(尽管希望人们不会依赖它)。
-
据我所知,我对此有什么误解?在我看来,您不知道满足条件的最后一项是在开头还是结尾,要找出哪个,无论如何您都必须遍历所有元素。我错过了什么?
标签: c# .net linq extension-methods ienumerable