Sobes.tech
Junior

Que tipos de objetos podem ser usados no ciclo foreach em C#?

sobes.tech IA

Resposta da IA

No ciclo foreach em C#, pode usar qualquer tipo de objetos que implementem uma das seguintes interfaces:

  • System.Collections.IEnumerable - Para coleções não genéricas. Fornece um enumerador não genérico IEnumerator.
  • System.Collections.Generic.IEnumerable<T> - Para coleções genéricas. Fornece um enumerador genérico IEnumerator<T>.

Uma classe ou estrutura também pode ser usada no foreach se tiver um método público GetEnumerator(), que retorna uma instância de uma classe ou estrutura que implementa a seguinte assinatura (isto é chamado foreach baseado em padrão):

  • Propriedade pública Current, que retorna qualquer tipo.
  • Método público MoveNext(), que retorna bool.
  • Opcionalmente, método público Dispose() (para liberar recursos corretamente ao usar using).

Exemplos de tipos integrados que podem ser usados:

  • Arrays (int[], string[], etc.)
  • Coleções do namespace System.Collections: ArrayList, Hashtable, Queue, Stack.
  • Coleções do namespace System.Collections.Generic: List<T>, Dictionary<TKey, TValue>, HashSet<T>, Queue<T>, Stack<T>.
  • Strings (string) - que são sequências de caracteres char.

Exemplo de um tipo personalizado que suporta foreach seguindo o padrão:

// Tipo personalizado simples que suporta foreach
public class MyEnumerable
{
    private int[] data = { 1, 2, 3, 4, 5 };

    // Método GetEnumerator que suporta foreach de acordo com o padrão
    public MyEnumerator GetEnumerator()
    {
        return new MyEnumerator(data);
    }

    // Classe interna do enumerador
    public class MyEnumerator
    {
        private int[] data;
        private int currentIndex = -1;

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

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

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

        // Método Dispose (opcional)
        public void Dispose()
        {
            // Liberação de recursos, se necessário
        }
    }
}

// Uso no foreach
// var collection = new MyEnumerable();
// foreach (var item in collection)
// {
//     // Console.WriteLine(item);
// }