Est-il possible d'avancer un énumérateur et d'obtenir sa valeur dans un lambda?
Question
Si j’ai une variable IEnumerator, est-il possible d’avoir une fonction lambda qui la prend, l’avance avec MoveNext () et renvoie la valeur Current chaque fois qu’elle est appelée?
La solution
e => e.MoveNext() ? e.Current : null
Ceci fera avancer l'énumérateur et renverra la valeur actuelle, ainsi que null lorsque l'énumération sera terminée.
Autres conseils
Une expression Lambda peut contenir des instructions complexes. Vous pouvez donc effectuer les opérations suivantes:
Func<IEnumerator, object> f = ie => { ie.MoveNext(); return ie.Current; };
Est-ce ce que vous cherchez?
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 + " ");
}
L'intérêt d'un IEnumerator
est que vous obtenez déjà un sucre syntaxique pour le gérer:
foreach (string str in strings)
Console.Write(str + " ");
Même la manipulation de l'énumérateur a l'air plus propre dans ce cas:
while (e.MoveNext())
Console.Write(e.Current + " ");
En prolongeant la solution d’Abe, vous pouvez également utiliser des fermetures pour contenir une référence à l’énumérateur:
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));
}