Iteratory i yield return w języku C#

Iterowanie - przechodzenie po elementach kolekcji.


Iteratory to nowość wprowadzona w C# 2.0. Iteratory pozwalają uprościć iterowanie czyli przechodzenie po kolejnych elementach kolekcji. Dzięki iteratorom nie musimy implementować interfejsu IEnumerator wraz z jego elementami (Reset(), MoveNext(), Current). Kompilator automatycznie generuje te metody, gdy używamy słowa kluczowego yield return, służącego do zwracania wartości z pętli. Gdy używamy iteratorów możemy zaimplementować metodę GetEnumerator() prosto w naszej klasie bez implementacji całej klasy Enumerator.

Przykładowy kod z użyciem yield return:

public class Program
{
    private static IEnumerable<int> PobierzDane()
    {
        Console.WriteLine("Początek metody PobierzDane.");
 
        List<int> list = new List<int>();
 
        for (int i = 1; i <= 10; i++)
        {
            Console.WriteLine("Aktualna wartość: {0}", i);
            yield return i;
        }
 
        Console.WriteLine("Koniec metody PobierzDane.");
    }
 
    public static void Main()
    {
        Console.WriteLine("Pobranie danych.");
        IEnumerable<int> data = PobierzDane();
 
        Console.WriteLine("Rozpoczęcie pętli.");
        foreach (int i in data)
        {
            Console.WriteLine("Odczyt wartości w pętli: {0}", i);
            if (i > 6)
                break;
        }
 
        Console.WriteLine("Koniec programu.");
        Console.ReadLine();
    }
}

Kod metody PobierzDane() bez użycia yield return:

private static IEnumerable<int> PobierzDane()
{
    Console.WriteLine("Początek metody PobierzDane.");
 
    List<int> list = new List<int>();
 
    for (int i = 1; i <= 10; i++)
    {
        Console.WriteLine("Aktualna wartość: {0}", i);
        list.Add(i);
    }
 
    Console.WriteLine("Koniec metody PobierzDane.");
    return list;
 
}

Porównanie działania metod:

yield return

Podsumowanie działania metod:

Metoda korzystająca z yield zwracała sekwencyjnie dane w pętli i je wyświetlała, natomiast metoda z listą pobrała całą listę a następnie wyświetliła te dane, które były potrzebne. Powyższy program działał bez użycia niestandardowego iteratora. W kolejnym przykładzie zostanie przedstawiony iterator zwracający co 2 element. Pętla została zabezpieczona przed wykroczeniem poza zakres tablicy.

Iterator zwracający co 2 element kolekcji

public class Iterator
{
    public int[] kolekcja;
    public Iterator()
    {
        kolekcja = new int[] {1,2,3,4,5,6,7,8,9 };
    }
    public System.Collections.IEnumerable PrzykladowyIterator()
    {
        for (int index = 1; index <= kolekcja.Length-1; index += 2)
        {
            System.Console.WriteLine("Iterator zwraca element nr: " + (index+1));
            yield return kolekcja[index];
        }
    }
}
 
public class Program
{
    public static void Main()
    {
        Iterator iterator = new Iterator();
 
        // Wyswietlanie kolekcji
        System.Console.WriteLine("Kolekcja wyświetlana co 2 element:");
            
        foreach (int i in iterator.PrzykladowyIterator())
        {
            System.Console.WriteLine("Pętla programu wyświetla element:" + i);
        }
 
        Console.ReadLine();
    }
}

Wynik działania programu:

Kolekcja wyświetlana co 2 element:
Iterator zwraca element nr: 2
Pętla programu wyświetla element: 2
Iterator zwraca element nr: 4
Pętla programu wyświetla element: 4
Iterator zwraca element nr: 6
Pętla programu wyświetla element: 6
Iterator zwraca element nr: 8
Pętla programu wyświetla element: 8

Więcej informacji na temat iteratorów i yield return:

http://msdn.microsoft.com/pl-pl/library/dscyy5s0.aspx
Komentarze facebook (polub nasz profil na FB aby je zobaczyć):