English 中文(简体)
What is the reason for IEnumerable/IEnumerable<T> interfaces to only have MoveNext?
原标题:

Basically I am wondering why MS decided to implement an enumerator that only supports going forward: MoveNext().

Is it not more flexible to also enforce MovePrevious for this widely used interface throughout the .NET framework?

I can imagine it making the Linq.Reverse far easier to implement for MS and more efficient in performance, but I am not sure if this makes other things slower or puts a massive overhead on everything else.

Anyone with more knowledge in this subject can give more info on this please? i.e. the pros and cons of having or not having MovePrevious in IEnumerable/IEnumerable<T>.

问题回答

IEnumerable[<T>] represents a sequence of data, not a random-access list. Not all sequences can be reversed, or even replayed. Sequences based on network streams, database access, etc - or this beauty:

IEnumerable<int> GetData() {
    Random rand = new Random();
    while(true) { yield return rand.Next(); }
}

The best you can do is start again - not by calling Reset() (which is deprecated), but by getting a fresh enumerator instead.

Even without Random it is trivial to come up with simple sequences that cannot be reversed (without buffering and reversing the buffer). For what you want, consider looking at IList[<T>] instead - you can access data via the indexer in any order.

There are many types of data where it does not make sense to have a MovePrevious. For example, if you are receiving data from a network connection, providing a MovePrevious would require buffering the entire stream just in case you called that method. This would waste huge amounts of memory.

Having said that, it might be useful to have a different type which supported both MoveNext and MovePrevious (a doubly linked list could support this, for example).

Usage convenience isn t the only factor involved when designing an interface ... you have to take into account how versatile it ll be and how what constraints you are adding to it.

There are sequences that can t be replayed, and you d be adding a lot of unnecessary requirements to implementing it.

There are other interfaces besides it, like IList, IQueryable. Using the most appropriate for the scenario, also communicates the type of usage that it should have.

Implementing a MovePrevious would make it much heavier interface. While for some sources (array, Container classes) a MovePrevious would be trivial, for a lot of other sources it would require expensive buffering, or exclude those sources. Network streams and Database connections do not support Seek operations.

It s to do with the pattern regarding "yield". Effectively enumerators are the simplest possible collection, you simply start at the front and take until the very end. This means that they code to implement the enumeration is extremely simple.

Also you can have functional code using iterators which never "end" as such, for instance

yield value++;

You will simply receive incrementing numbers until you stop.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签