为什么C#中没有ReverseEnumerator?
有谁知道是否有特定原因或设计决定不在 C# 中包含反向枚举器?如果有一个与 C++ reverse_iterator
等效的东西,就像 Enumerator 与 C++ iterator
等效一样,那就太好了。可以反向迭代的集合只需实现类似 IReverseEnumerable 的功能,并且可以执行以下操作:
List<int>.ReverseEnumerator ritr = collection.GetReverseEnumerator();
while(rtir.MoveNext())
{
// do stuff
}
这样,您将能够以相同的方式迭代列表和 LinkedList,而不是对一个使用索引器,对另一个使用前一个链接,从而实现更好的抽象
Does anyone know if there was a specific reason or design decision to not include a reverse enumerator in C#? It would be so nice if there was an equivalent to the C++ reverse_iterator
just like Enumerator is the equivalent of the C++ iterator
. Collections that can be reverse-iterated would just implement something like IReverseEnumerable and one could do something like:
List<int>.ReverseEnumerator ritr = collection.GetReverseEnumerator();
while(rtir.MoveNext())
{
// do stuff
}
This way, you would be able to iterate Lists and LinkedLists in the same way rather than using indexer for one and previous links for the other thus achieving better abstraction
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
实现这一点是完全有可能的。就我个人而言,我几乎从不进行反向迭代。如果我需要这样做,我首先调用 .Reverse() 。也许这也是 .NET BCL 设计者的想法。
这就是为什么您不实现实用性不大的功能的原因。您从最重要的功能开始(例如从前到后迭代)。你会在某个地方停下来,要么你的预算已经耗尽,要么你认为没有必要继续下去。
有很多东西不在.NET 基类库中。在 .NET 4 之前,甚至还没有
File.EnumerateLines
。我敢说,对于大多数人来说,这样的功能比反向迭代更重要。您可能在逆向迭代很常见的业务领域工作。我的经历恰恰相反。作为框架设计者,您只能猜测谁将使用您的框架以及这些人将需要哪些功能。很难划清界限。
It would be entirely possible to implement this. Personally, I almost never reverse-iterate. If I need to do this, I call .Reverse() first. Probably this is what the .NET BCL designers thought as well.
And this is why you don't implement features that provide little utility. You start with the most important features (like iterating front-to-back). And you stop somewhere where either your budget is depleted or where you think is does not make sense to continue.
There are many things that are not in the .NET base class library. Until .NET 4 there even wasn't a
File.EnumerateLines
. And I would venture to say that such a functionality is more important than reverse iteration for most people.It might be the case that you are working in a business domain where reverse iteration is common. My experience is the opposite. As a framework designer you can only guess who will use your framework and what features these people will demand. It is hard to draw the line.
它不可用,因为
IEnumerator
是仅向前迭代器。它只有一个MoveNext()
方法。这使得该接口非常通用,并且是 Linq 的核心。有很多现实世界的集合无法向后迭代,因为这需要存储。例如,大多数流都是这样的。Linq 提供了带有
Reverse()
扩展方法的解决方案。它的工作原理是首先存储元素,然后向后迭代它们。然而,这可能非常浪费,它需要 O(n) 存储。它缺少对已经可索引的集合的可能优化。您可以修复:示例用法:
您需要对 LinkedList 进行专门化,因为它没有实现
IList
,但仍然允许通过Last
和LinkedListNode.Previous
属性。尽管不使用该类要好得多,但它的 CPU 缓存局部性很差。当您不需要便宜的插入时,始终青睐List
。它可能看起来像这样:It isn't available because
IEnumerator
is a forward only iterator. It only has aMoveNext()
method. That makes the interface very universal and the core of Linq. There are lots of real world collections that cannot be iterated backwards because that requires storage. Most streams are like that for example.Linq provides a solution with the
Reverse()
extension method. It works by storing the elements first, then iterating them backwards. That however can be very wasteful, it requires O(n) storage. It is missing a possible optimization for collections that are already indexable. Which you can fix:Sample usage:
You'll want to make a specialization for LinkedList since it doesn't implement
IList<T>
but still allows quick backwards iteration through theLast
andLinkedListNode.Previous
properties. Although it is much better to not use that class, it has lousy CPU cache locality. Always favorList<T>
when you don't need cheap inserts. It could look like this:线索就在OP的最后一行:在列表和链接列表上使用它。
因此,对于
List
来说,这个可以很好地工作:使用
IReadOnlyList
在其工作方面提供了很大的灵活性。对于
LinkedLists
来说,类似的事情也是可能的。The clue is in the OP's final line: using this on Lists and LinkedLists.
So, for a
List
, this one would work nicely:Using
IReadOnlyList
give a lot of flexibility in terms of what it will work on.Something similar would be possible for
LinkedLists
.这个问题涉及一个枚举器,而不是一个枚举。
如果必须返回 IEnumerator(例如,当绑定到 wpf / uwp / winui 中的自定义数据源对象时),您可以这样做:
丑陋、复杂且有效,即完全遵守框架指南。
The question concerns an enumerator, not an enumeration.
If you must return an IEnumerator (e.g. when binding to a custom datasource object in wpf / uwp / winui), you can do it like this:
Ugly, convoluted and working, i.e. fully adhering to Framework Guidelines.
是的,你可以轻松做到。
只需使用
Stack
就像
Yes, you can do it easily.
Just use
Stack<T>
Like