Sobes.tech
Junior

Ce tipuri de obiecte pot fi utilizate într-o buclă foreach în C#?

sobes.tech AI

Răspuns de la AI

În bucla foreach în C# pot fi utilizate orice tipuri de obiecte care implementează unul dintre următoarele interfețe:

  • System.Collections.IEnumerable - Pentru colecții non-generice. Oferă un enumerator non-generic IEnumerator.
  • System.Collections.Generic.IEnumerable<T> - Pentru colecții generice. Oferă un enumerator generic IEnumerator<T>.

O clasă sau structură poate fi, de asemenea, utilizată în foreach dacă are o metodă publică GetEnumerator(), care returnează o instanță a unei clase sau structuri care implementează următoarea semnătură (aceasta se numește foreach bazat pe pattern):

  • Proprietate publică Current, care returnează orice tip.
  • Metodă publică MoveNext(), care returnează bool.
  • Opțional, metodă publică Dispose() (pentru eliberarea corectă a resurselor la utilizarea using).

Exemple de tipuri încorporate care pot fi utilizate:

  • Arrays (int[], string[], etc.)
  • Colecții din spațiul de nume System.Collections: ArrayList, Hashtable, Queue, Stack.
  • Colecții din spațiul de nume System.Collections.Generic: List<T>, Dictionary<TKey, TValue>, HashSet<T>, Queue<T>, Stack<T>.
  • Șiruri (string) - acestea sunt secvențe de caractere char.

Exemplu de tip personalizat care suportă foreach conform pattern-ului:

// Tip personalizat simplu care suportă foreach
public class MyEnumerable
{
    private int[] data = { 1, 2, 3, 4, 5 };

    // Metodă GetEnumerator care suportă foreach conform pattern-ului
    public MyEnumerator GetEnumerator()
    {
        return new MyEnumerator(data);
    }

    // Clasă internă a enumeratorului
    public class MyEnumerator
    {
        private int[] data;
        private int currentIndex = -1;

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

        // Proprietate Current
        public int Current => data[currentIndex];

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

        // Metodă Dispose (opțional)
        public void Dispose()
        {
            // Eliberarea resurselor dacă este necesar
        }
    }
}

// Utilizare în `foreach`
// var collection = new MyEnumerable();
// foreach (var item in collection)
// {
//     // Console.WriteLine(item);
// }