Sobes.tech
Junior

Какви типове обекти могат да се използват в цикъла foreach в C#?

sobes.tech AI

Отговор от AI

В цикъла foreach в C# можете да използвате всякакви типове обекти, които реализират един от следните интерфейси:

  • System.Collections.IEnumerable - За неуниверсални колекции. Предоставя неуниверсален итератор IEnumerator.
  • System.Collections.Generic.IEnumerable<T> - За универсални колекции. Предоставя универсален итератор IEnumerator<T>.

Клас или структура също могат да се използват в foreach, ако имат публичен метод GetEnumerator(), който връща екземпляр на клас или структура, реализиращи следната сигнатура (това се нарича foreach базиран на шаблон):

  • Публично свойство Current, което връща всеки тип.
  • Публичен метод MoveNext(), който връща bool.
  • По желание, публичен метод Dispose() (за правилно освобождаване на ресурсите при използване using).

Примери за вградени типове, които могат да се използват:

  • Масиви (int[], string[] и т.н.)
  • Колекции от пространството имена System.Collections: ArrayList, Hashtable, Queue, Stack.
  • Колекции от пространството имена System.Collections.Generic: List<T>, Dictionary<TKey, TValue>, HashSet<T>, Queue<T>, Stack<T>.
  • Стринг (string) - те са последователност от символи char.

Пример за потребителски тип, който поддържа foreach по шаблон:

// Прост потребителски тип, поддържащ `foreach`
public class MyEnumerable
{
    private int[] data = { 1, 2, 3, 4, 5 };

    // Метод GetEnumerator, поддържащ `foreach` по шаблон
    public MyEnumerator GetEnumerator()
    {
        return new MyEnumerator(data);
    }

    // Вътрешен клас-енумратор
    public class MyEnumerator
    {
        private int[] data;
        private int currentIndex = -1;

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

        // Свойство Current
        public int Current => data[currentIndex];

        // Метод MoveNext
        public bool MoveNext()
        {
            currentIndex++;
            return currentIndex < data.Length;
        }

        // Метод Dispose (по желание)
        public void Dispose()
        {
            // Освобождаване на ресурси, ако е необходимо
        }
    }
}

// Използване в `foreach`
// var collection = new MyEnumerable();
// foreach (var item in collection)
// {
//     // Console.WriteLine(item);
// }