There is a close correspondence between the Java interface Iterable
and
C#'s IEnumerable
; and similarly between Java's Iterator
and C# IEnumerator
.
In both cases the interface is closely tied up with the ability to write a
"for each" loop. If we're going to be able to translate this Java:
for (Attribute att : attributes) {...}
into this C#:
foreach(Attribute att in attributes) {...}
then the variable attributes
, which is an Iterable
in Java, had better become
an IEnumerable
in C#. We can handle that by rewriting class names; and we can also
rewrite the method attributes.iterator()
as attributes.GetEnumerable()
so that it
satisfies the C# interface. What now gets tricky is that Java's Iterator
has two
methods hasNext()
and next()
which don't correspond neatly to C# IEnumerator
,
which has MoveNext()
and Current
. Specifically, hasNext()
is stateless, and can
be called any number of times, while MoveNext()
is state-changing and can only
be called once. However, "sane" code that uses an iterator always makes one call
on hasNext()
followed by one call on next()
, and that sequence translates directly
to a call on MoveNext()
followed by a call on Current
. So the converter assumes
that the code will follow this discipline – and if we find code that doesn't,
then we have to change it[11].
[11] A benefit of having the parsed Java code in XML format is that it's easy to do queries to search for code that needs to be inspected.