When I first made the transition into C# as a intermediate (or maybe Novice) Java programmer, I was not quite used to C#'s enumerator interface with its 'MoveNext()' and 'Current' scheme. I thought it was merely trying to be different from Java for no reason.
Now that I had to write an iterator that tries to enumerate all cycles in a graph, I finally see the pain in the ass of Java.
Nevermind the lack of "yield return" keyword which makes the code a lot more readable and easier to implement. I can kind of respect Java's decision not to include that keyword as it kind of abstract too much of what compiler will be doing. (I am aware of JYield, it's a brillant design but it has its drawbacks. I am not sure about the efficiency of this thing as it is kind of a hack and also it makes the code completely unreadable to people who has not heard of this package)
anyway, I digress
As I am writing my cycle iterator, I found it very troublesome to implement hasNext() and next() method. It is impossible to tell if the graph has a next cycle without advancing the state of my iterator. It would be a pain in the ass to make my program behave as the interface suggested. I will have to keep track of which method (either hasNext() or next() was call last and modify the behavior accordingly) I am just going to give up and make hasNext() behave like MoveNext() in C# and make next() behave like Current.
Peter Hsu wrote:I am just going to give up and make hasNext() behave like MoveNext() in C# and make next() behave like Current.
Instead of doing that, why not just write a class which has current() and moveNext() methods? It wouldn't be an Iterator, but do you really need an Iterator?
And yeah, when I wrote a ResultSetIterator, I did have to write that look-ahead logic which you complain about. I didn't find it a pain anywhere.
Joined: Aug 25, 2006
thanks Cambell and Paul for your reply.
I do need to keep my classes as Iterable because i want the user to be able to easily put the results in a pre-defined data structure like a collection or array and I am unwilling to write more boilerplate code.
I guess my point can arguably be moot because there is a way to implement the look ahead logic. A lot of non-trivial iterator would require this kind of logic to behave as the interface specified. It is even possible to define a base class IteratorBase with the finalized method hasNext() and next() implementing this look ahead logic and allow user to override MoveNext() and getCurrent(), but it just shows that MoveNext(), Current scheme is more natural. In cases where we don't know if the iterable will end, peeking ahead is just as expensive as moving forward, we should just as well move forward.
Joined: Aug 25, 2006
I don't mind sharing my code as an example because it is just an exercise actually.