22
août
2007
Récupérer un IEnumerable par morceau
août
2007
Comment récupérer un IEnumerable par morceau ?
Avec son Enumerator bien sûr. Ok jusque là c’est pas très dur.
Cependant l’avantage d’un IEnumerable c’est de pouvoir faire un foreach dessus. Et le foreach commence par faire un reset sur le IEnumerable, ce qui nous fait perdre l’état courant.
Du coup, comment récupérer un IEnumerable par morceau sous la forme d’un IEnumerable ?
Voilà la solution que je propose :
public static class Test
{
private static IEnumerator<int> _enumerator;
public static IEnumerator<int> Enumerator
{
get
{
if (_enumerator == null)
_enumerator = Enumerable().GetEnumerator();
return _enumerator;
}
}
public static IEnumerable<int> EnumerableByStep(Func<bool> continueCondition)
{
while (continueCondition() && Enumerator.MoveNext())
yield return Enumerator.Current;
}
private static IEnumerable<int> Enumerable()
{
for (int i = 0; i < 100; i++)
yield return i;
}
}
{
private static IEnumerator<int> _enumerator;
public static IEnumerator<int> Enumerator
{
get
{
if (_enumerator == null)
_enumerator = Enumerable().GetEnumerator();
return _enumerator;
}
}
public static IEnumerable<int> EnumerableByStep(Func<bool> continueCondition)
{
while (continueCondition() && Enumerator.MoveNext())
yield return Enumerator.Current;
}
private static IEnumerable<int> Enumerable()
{
for (int i = 0; i < 100; i++)
yield return i;
}
}
Le code suivant :
int nb = 0;
foreach (int i in Test.EnumerableByStep(() => nb++ < 5))
Console.WriteLine("1 : " + i.ToString());
nb = 0;
foreach (int i in Test.EnumerableByStep(() => nb++ < 5))
Console.WriteLine("2 : " + i.ToString());
foreach (int i in Test.EnumerableByStep(() => nb++ < 5))
Console.WriteLine("1 : " + i.ToString());
nb = 0;
foreach (int i in Test.EnumerableByStep(() => nb++ < 5))
Console.WriteLine("2 : " + i.ToString());
écrira dans la console
1 : 0
1 : 1
1 : 2
1 : 3
1 : 4
2 : 5
2 : 6
2 : 7
2 : 8
2 : 9
Le fait de pouvoir récupérer l’enumerator vous permet également de le passer à une autre méthode :
class Program
{
static void Main(string[] args)
{
int nb = 0;
foreach (int i in Test.EnumerableMod2ByStep(() => nb++ < 10))
Console.WriteLine("1 : " + i.ToString());
nb = 0;
foreach (int i in EnumerableMod3ByStep(Test.Enumerator, () => nb++ < 10))
Console.WriteLine("2 : " + i.ToString());
Console.ReadLine();
}
public static IEnumerable<int> EnumerableMod3ByStep(IEnumerator<int> enumerator, Func<bool> continueCondition)
{
while (continueCondition() && enumerator.MoveNext())
if (enumerator.Current % 3 == 0)
yield return enumerator.Current;
}
}
public static class Test
{
private static IEnumerator<int> _enumerator;
public static IEnumerator<int> Enumerator
{
get
{
if (_enumerator == null)
_enumerator = Enumerable().GetEnumerator();
return _enumerator;
}
}
public static IEnumerable<int> EnumerableMod2ByStep(Func<bool> continueCondition)
{
while (continueCondition() && Enumerator.MoveNext())
if (Enumerator.Current % 2 == 0)
yield return Enumerator.Current;
}
private static IEnumerable<int> Enumerable()
{
for (int i = 0; i < 100; i++)
yield return i;
}
}
{
static void Main(string[] args)
{
int nb = 0;
foreach (int i in Test.EnumerableMod2ByStep(() => nb++ < 10))
Console.WriteLine("1 : " + i.ToString());
nb = 0;
foreach (int i in EnumerableMod3ByStep(Test.Enumerator, () => nb++ < 10))
Console.WriteLine("2 : " + i.ToString());
Console.ReadLine();
}
public static IEnumerable<int> EnumerableMod3ByStep(IEnumerator<int> enumerator, Func<bool> continueCondition)
{
while (continueCondition() && enumerator.MoveNext())
if (enumerator.Current % 3 == 0)
yield return enumerator.Current;
}
}
public static class Test
{
private static IEnumerator<int> _enumerator;
public static IEnumerator<int> Enumerator
{
get
{
if (_enumerator == null)
_enumerator = Enumerable().GetEnumerator();
return _enumerator;
}
}
public static IEnumerable<int> EnumerableMod2ByStep(Func<bool> continueCondition)
{
while (continueCondition() && Enumerator.MoveNext())
if (Enumerator.Current % 2 == 0)
yield return Enumerator.Current;
}
private static IEnumerable<int> Enumerable()
{
for (int i = 0; i < 100; i++)
yield return i;
}
}