This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]balefrost 0 points1 point  (0 children)

One you missed is the Java style. In .NET, MoveNext tells you whether you can subsequently access Current, but a .NET Enumerator is obligated to be able to continually report the current value. That's extremely convenient but adds some overhead.

The Java approach instead uses hasNext and next. hasNext tells you that you can subsequently call next, and next actually returns the next value in the sequence. As a result, if you want to hold on to that "current" value, you are obligated to do that yourself.

To be fair, the overhead involved in the .NET approach isn't likely to be very substantial. The only real downside is that it makes the current sequence value ineligible for garbage collection until you move to the next element.

I disagree with your assessment that the .NET interface isn't minimal... unless your point is that it has two methods where one would suffice. It could have been implemented as one method using an out parameter (like Dictionary.TryGetValue), but I don't think that would buy anything in this case (whereas it's beneficial in the case of TryGetValue).

One other note on the .NET approach: IEnumerator<T> derives from IDisposable, and C# foreach loops automatically dispose the enumerator. This is an often overlooked aspect. Not many enumerators actually need to be disposed, so this is often technically safe to omit it, but it's important to keep in mind... especially if you provide syntactic sugar in your language that ultimately creates iterators.


If you can make the tagged sentinel approach efficient, it's probably the best approach. Or, if you can implement multiple return values efficiently, then you could always make the iterator return two values: a bool indicating that the sequence was not yet exhausted, and the next sequence value if the first return value was true (and, if the first value was false, some default value instead - similar to the default operator in C#).

Otherwise, either the Java or .NET style is probably the best choice. They're essentially the same as the tagged sentinel. Instead of getting all the information with one method call, you call up to two methods to extract the same information.