tags:

views:

205

answers:

4

If I have an IEnumerator variable is it possible to have a lambda function that takes it, advances it with MoveNext() and returns the Current value every single time its called?

+1  A: 

A Lambda expression can contain complex statements, so you can do the following:

Func<IEnumerator, object> f = ie => { ie.MoveNext(); return ie.Current; };
Abe Heidebrecht
thanks, just couldn't find the syntax
George Mauer
+3  A: 
e => e.MoveNext() ? e.Current : null

This will advance the enumerator and return the current value, and return null when the enumeration is complete.

Jonathan
A: 

Is this what you are looking for?

List<string> strings = new List<string>()
{
    "Hello", "I", "am", "a", "list", "of", "strings."
};
IEnumerator<string> e = strings.GetEnumerator();
Func<string> f = () => e.MoveNext() ? e.Current : null;
for (; ; )
{
    string str = f();
    if (str == null)
        break;

    Console.Write(str + " ");
}

The point of an IEnumerator is that you already get syntactic sugar to deal with it:

foreach (string str in strings)
    Console.Write(str + " ");

Even handling the enumerator directly looks cleaner in this case:

while (e.MoveNext())
    Console.Write(e.Current + " ");
fryguybob
A: 

Extending on Abe's solution, you can also use closures to hold a reference to the enumerator:

var iter = ((IEnumerable<char>)"hello").GetEnumerator();

//with closure
{
    Func<object> f =
        () =>
            {
                iter.MoveNext();
                return iter.Current;
            };
    Console.WriteLine(f());
    Console.WriteLine(f());
}

//without closure
{
    Func<IEnumerator, object> f =
        ie =>
            {
                ie.MoveNext();
                return ie.Current;
            };
    Console.WriteLine(f(iter));
    Console.WriteLine(f(iter));
}
Nathan Baulch