Skip to content

Zadanie 14

Podać przykłady potwierdzające przydatność konstrukcji foreach

Pętla foreach iteruje po wszystkich elementach kolekcji bez ręcznego operowania indeksem. Działa na każdym typie implementującym interfejs IEnumerable (tablice, listy, słowniki). Jest czytelniejsza i mniej podatna na błędy niż klasyczna pętla for, bo nie grozi wyjściem poza zakres indeksu.

// iteracja po tablicy
int[] numbers = { 1, 2, 3 };
foreach (int n in numbers)
{
Console.WriteLine(n);
}
// iteracja po liście
List<string> names = new List<string> { "Ala", "Ola" };
foreach (string name in names)
{
Console.WriteLine(name);
}
// iteracja po słowniku - element to para klucz-wartość
Dictionary<string, int> ages = new Dictionary<string, int> { { "Ala", 20 } };
foreach (var pair in ages)
{
Console.WriteLine(pair.Key + ": " + pair.Value);
}

Foreach działa też na własnych klasach, jeśli zaimplementują interfejs IEnumerable (metodę GetEnumerator). Najprościej zrobić to słowem kluczowym yield return, które samo generuje enumerator.

// własna klasa, po której da się iterować foreach
class Team : IEnumerable
{
// dane trzymamy wewnątrz w zwykłej tablicy
private string[] players = { "Ala", "Ola", "Ela" };
// GetEnumerator mówi, jak foreach ma przechodzić po elementach
// yield return oddaje kolejne elementy jeden po drugim
public IEnumerator GetEnumerator()
{
foreach (string player in players)
yield return player;
}
}
// foreach po własnej klasie działa dzięki GetEnumerator
foreach (var player in new Team())
Console.WriteLine(player);

Podczas działania foreach nie wolno zmieniać struktury kolekcji (dodawać ani usuwać elementów), bo grozi to wyjątkiem InvalidOperationException. Wolno za to zmieniać właściwości obiektów, gdy elementy są typami referencyjnymi.


Skrót do zapamiętania: foreach iteruje po wszystkich elementach kolekcji (każdej z IEnumerable) bez indeksu. Czytelniejsza i bezpieczniejsza niż for (brak wyjścia poza zakres). Implementując IEnumerable (np. przez yield return), można dać foreach także własnej klasie.

  • Działa na wszystkim, co implementuje IEnumerable (tablice, listy, słowniki).
  • Bez ręcznego indeksu i licznika -> mniej błędów.
  • Brak ryzyka wyjścia poza zakres.
  • Czytelnie wyraża “przejdź po wszystkich”; minus: nie ma dostępu do indeksu.
  • W trakcie foreach nie wolno zmieniać struktury kolekcji (Add/Remove -> InvalidOperationException); można zmieniać właściwości obiektów referencyjnych.
  • Własna klasa też może wspierać foreach: wystarczy zaimplementować IEnumerable (GetEnumerator), najłatwiej przez yield return.