Sobes.tech
Junior

Jakie typy obiektów można używać w pętli foreach w C#?

sobes.tech AI

Odpowiedź od AI

W pętli foreach w C# można używać dowolnych typów obiektów implementujących jeden z następujących interfejsów:

  • System.Collections.IEnumerable - dla kolekcji niegenerycznych. Zapewnia niegenerycznego enumeratora IEnumerator.
  • System.Collections.Generic.IEnumerable<T> - dla kolekcji generycznych. Zapewnia generycznego enumeratora IEnumerator<T>.

Klasa lub struktura mogą być również używane w foreach, jeśli mają publiczną metodę GetEnumerator(), która zwraca instancję klasy lub struktury implementującej następującą sygnaturę (nazywa się to foreach opartym na wzorcu):

  • Publiczna właściwość Current, zwracająca dowolny typ.
  • Publiczna metoda MoveNext(), zwracająca bool.
  • Opcjonalnie, publiczna metoda Dispose() (do poprawnego zwalniania zasobów podczas użycia using).

Przykłady wbudowanych typów, które można używać:

  • Tablice (int[], string[] itd.)
  • Kolekcje z przestrzeni nazw System.Collections: ArrayList, Hashtable, Queue, Stack.
  • Kolekcje z przestrzeni nazw System.Collections.Generic: List<T>, Dictionary<TKey, TValue>, HashSet<T>, Queue<T>, Stack<T>.
  • Ciągi znaków (string) - są sekwencjami znaków char.

Przykład typu własnego, obsługującego foreach według wzorca:

// Prosty własny typ obsługujący foreach
public class MyEnumerable
{
    private int[] data = { 1, 2, 3, 4, 5 };

    // Metoda GetEnumerator obsługująca foreach według wzorca
    public MyEnumerator GetEnumerator()
    {
        return new MyEnumerator(data);
    }

    // Wewnętrzna klasa enumeratora
    public class MyEnumerator
    {
        private int[] data;
        private int currentIndex = -1;

        public MyEnumerator(int[] data)
        {
            this.data = data;
        }

        // Właściwość Current
        public int Current => data[currentIndex];

        // Metoda MoveNext
        public bool MoveNext()
        {
            currentIndex++;
            return currentIndex < data.Length;
        }

        // Metoda Dispose (opcjonalna)
        public void Dispose()
        {
            // Zwolnienie zasobów, jeśli konieczne
        }
    }
}

// Użycie w foreach
// var collection = new MyEnumerable();
// foreach (var item in collection)
// {
//     // Console.WriteLine(item);
// }