有人知道是否有特定原因或设计决定不在C#中包含反向调查员?如果有一个与C ++相同的reverse_iterator
,就像Enumerator相当于C ++ iterator
一样,那就太好了。可以反向迭代的集合只会实现像IReverseEnumerable这样的东西,可以做类似的事情:
List<int>.ReverseEnumerator ritr = collection.GetReverseEnumerator();
while(rtir.MoveNext())
{
// do stuff
}
这样,您就可以以相同的方式迭代Lists和LinkedLists,而不是为另一个链接使用索引器,从而实现更好的抽象
答案 0 :(得分:21)
完全可以实现这一点。就个人而言,我几乎从不反向迭代。如果我需要这样做,我先调用.Reverse()。可能这也是.NET BCL设计师所想的。
默认情况下,所有功能都未实现。它们需要设计,实施,测试,记录和支持。 - Raymond Chen
这就是为什么你不实现提供很少实用性的功能。您从最重要的功能开始(例如从前到后迭代)。而且你停在某个地方,你的预算已经耗尽,或者你觉得继续没有意义。
.NET基类库中有很多东西没有。直到.NET 4,甚至还没有File.EnumerateLines
。我敢说,对于大多数人来说,这种功能比反向迭代更重要。
可能是您在反向迭代很常见的业务领域工作。我的经历恰恰相反。作为框架设计师,您只能猜测谁将使用您的框架以及这些人将要求的功能。很难画线。
答案 1 :(得分:12)
它不可用,因为IEnumerable是一个前向迭代器。它只有一个MoveNext()方法。这使得界面非常普遍并且是Linq的核心。有许多真实世界的集合无法向后迭代,因为这需要存储。大多数流都是这样的。
Linq使用Reverse()扩展方法提供解决方案。它的工作原理是先存储元素,然后再向后迭代。然而,这可能非常浪费,它需要O(n)存储。它缺少对已经可索引的集合的可能优化。您可以修复:
static class Extensions {
public static IEnumerable<T> ReverseEx<T>(this IEnumerable<T> coll) {
var quick = coll as IList<T>;
if (quick == null) {
foreach (T item in coll.Reverse()) yield return item;
}
else {
for (int ix = quick.Count - 1; ix >= 0; --ix) {
yield return quick[ix];
}
}
}
}
样本用法:
var list = new List<int> { 0, 1, 2, 3 };
foreach (var item in list.ReverseEx()) {
Console.WriteLine(item);
}
你想要对LinkedList进行专门化,因为它没有实现IList&lt;&gt;但仍允许通过Last和LinkedListNode.Previous属性快速向后迭代。虽然不使用该类要好得多,但它具有糟糕的CPU缓存局部性。总是喜欢List&lt;&gt;当你不需要便宜的插入物。它看起来像这样:
public static IEnumerable<T> ReverseEx<T>(this LinkedList<T> list) {
var node = list.Last;
while (node != null) {
yield return node.Value;
node = node.Previous;
}
}
答案 2 :(得分:1)
线索在OP的最后一行:在Lists和LinkedLists上使用它。
因此,对于List
来说,这很好用:
public static IEnumerable<T> AsReverseEnumerator<T>(this IReadOnlyList<T> list)
{
for (int i = list.Count; --i >= 0;) yield return list[i];
}
使用IReadOnlyList
可以灵活地发挥作用。
LinkedLists
可能会有类似的事情。
答案 3 :(得分:0)
问题涉及枚举器,而不是枚举。 如果你必须返回一个 IEnumerator(例如绑定到 wpf/uwp/winui 中的自定义数据源对象时),你可以这样做:
var reverseList = myList.AsEnumerable().Reverse().ToList();
return reverseList.GetEnumerator()
丑陋、复杂且有效,即完全遵守框架指南。