C# -  Você sabe como funciona o foreach ?


A  instrução foreach é fácil de usar e muito usada mas você sabe como ela funciona ?

Neste artigo vamos apresentar como funciona a instrução foreach. Confira...

O que faz a instrução foreach ?

A instrução foreach executa uma instrução ou um bloco de instruções para cada elemento em uma instância do tipo que implementa a interface System.Collections.IEnumerable ou System.Collections.Generic.IEnumerable<T>.

A instrução foreach não está limitada a esses tipos e pode ser aplicada a uma instância de qualquer tipo que satisfaça as seguintes condições:

Com foreach você não precisa saber o tamanho da coleção antes de iniciar a iteração e não precisa usar um índice:

var nomes = new List<string>() { "Jose", "Tania", "Pedro" };

foreach (string nome in nomes)
{
   Console.WriteLine(nome);
}

Em qualquer ponto dentro do bloco de instrução foreach, você pode sair do loop usando a instrução break :

var nomes = new List<string>() { "Jose", "Tania", "Pedro" };

foreach (string nome in nomes)
{
    if (nome == "Tania")
    {
       break;
    }
    Console.WriteLine(nome);
}

ou seguir para a próxima iteração no loop usando a instrução continue.

var nomes = new List<string>() { "Jose", "Tania", "Pedro" };

foreach (string nome in nomes)
{
    if (nome == "Tania")
    {
         continue;
    }
    Console.WriteLine(nome);
}

Você também pode sair de um loop foreach com a instrução goto, return ou throw.(por sua conta e risco...)

Você sabia que foreach funciona de modo diferente para os arrays e para as coleções IEnumberable<T> ?

Exemplo usando Array:

int[] array = new int[] {1, 2, 3, 4, 5, 6};

foreach (int item in array)
{
     Console.WriteLine(item);
}

Quando este código é executado a instrução foreach é executada como uma instrução for/next.

Neste exemplo, por baixo dos panos, o foreach conta com o suporte da propriedade Length e do operador de indice, assim. usando o operador Length. ele pode usar a instrução for/next para iterar em cada elemento do array.

Exemplo usando IEnumerable<T>:

var nomes = new List<string>() { "Jose", "Tania", "Pedro", ......... , "Wilson" };

foreach (string nome in nomes)
{
   Console.WriteLine(nome);
}

Embora o código anterior funcione bem nos arrays, nas quais o comprimento é fixo e o operador de índice é sempre suportado, nem todos os tipos de coleções têm um número de elementos conhecido.

Além disso muitas das classes da coleção, inclusive Stack<T>, Queue<T> e Dictionary<TKey e TValue>, não suportam recuperar os elementos pelo índice.

Portanto, é necessária uma abordagem mais geral da iteração nas coleções de elementos, e, o padrão Iterator fornece esta capacidade.

Supondo que você possa determinar o primeiro, próximo e último elementos, é desnecessário saber a contagem e dar suporte à recuperação dos elementos pelo índice.

Se você não sabe a diferença entre IEnumerable<T> e IEnumerator<T> veja este artigo : .NET - As interface IEnumerable e IEnumerator

Usando foreach com IEnumerable com implementação de "Yield Return"

Implementar IEnumerable usando a declaração de retorno Yield é bem simples:

Exemplo:

using System;

namespace CShp_Iterator
{
    class Program
    {
        public static System.Collections.IEnumerable GetNumeros()
        {
            yield return 23;
            yield return 45;
            yield return 78;

        }

        static void Main(string[] args)
        {

            foreach (int numero in GetNumeros())
            {
                Console.Write(numero.ToString() + " ");
            }
            Console.ReadKey();
        }
    }
}

No código acima temos que:

Podemos também usar a instrução yield break para terminar a iteração.

"O Senhor é o meu rochedo, e o meu lugar forte, e o meu libertador; o meu Deus, a minha fortaleza, em quem confio; o meu escudo, a força da minha salvação, e o meu alto refúgio."
Salmos 18:2

Referências:


José Carlos Macoratti