Iterationsanweisungen

Tip

Dieser Artikel ist Teil des Abschnitts "Grundlagen" für Entwickler, die bereits mindestens eine Programmiersprache kennen und C# erlernen. Wenn Sie noch nicht mit der Programmierung vertraut sind, beginnen Sie zuerst mit den Lernprogrammen " Erste Schritte ". Die vollständige Syntax finden Sie in den Iterationsanweisungen in der Sprachreferenz.

Kommen Sie aus einer anderen Sprache? Alle vier C#-Schleifen (foreach, while,do-while und for) verfügen über direkte Entsprechungen in Java, C++ und JavaScript. Sie verwenden foreach am häufigsten. Es durchläuft eine Sammlung ohne Index, wie das erweiterte for von Java oder for...of von JavaScript.

Iterationsanweisungen führen wiederholt einen Codeblock aus. Jeder Durchlauf des Blocks ist eine Iteration, und ein wiederholter Block ist eine Schleife. C# stellt vier Schleifen bereit. Verwenden Sie für Sammlungen zunächst foreach, verwenden Sie while und do-while, wenn eine Bedingung die Wiederholung steuert, und verwenden Sie for, wenn Sie einen expliziten Index benötigen.

Durchlaufen einer Sammlung mit foreach

Die foreach-Anweisung führt den Textkörper einmal für jedes Element in einer Auflistung in der Reihenfolge aus. Sie ist die gängigste Wahl beim Lesen einer Sammlung, weil Sie weder einen Index verwalten noch eine Bereichsprüfung durchführen müssen. Die foreach-Anweisung verhindert typische Off-by-one-Fehler:

string[] names = ["Ana", "Ben", "Cleo"];

// foreach reads each element in order. It's the default loop for
// collections: no index to manage and no off-by-one mistakes.
foreach (string name in names)
{
    Console.WriteLine(name); // => Ana, then Ben, then Cleo
}

foreach funktioniert mit jedem Typ, den C# als Sequenz erkennt, einschließlich Arrays, List<T>und Dictionary<TKey,TValue>. Die Iterationsvariable (name im vorherigen Beispiel) ist schreibgeschützt, sodass Sie sie nicht innerhalb der Schleife neu zuweisen können.

Der Text einer Schleife ist eine einzelne Anweisung, beispielsweise eine Zuweisung oder ein Methodenaufruf. Eine Block-Anweisung ist selbst eine einzelne Anweisung, die null oder mehr Anweisungen in geschweifte Klammern ({ }) einschließt.

Viele Programmierstandards empfehlen, die Schleifentexte selbst bei nur einer Anweisung in geschweifte Klammern zu setzen. Geschweifte Klammern machen den Gültigkeitsbereich explizit. Es verhindert einen häufigen Fehler: später eine zweite Zeile hinzuzufügen, von der man erwartet, dass sie bei jeder Iteration ausgeführt wird, die stattdessen aber nur einmal nach der Schleife ausgeführt wird. Nur die geschweiften Klammern entscheiden, welche Anweisungen zur Schleife gehören. C# behandelt Leerzeichen nicht als signifikant, sodass der Einzug allein nie funktioniert. Geschweifte Klammern sind auch bei einer einzelnen Zeile zulässig: Der Block ist die eine Anweisung, die in dieser Schleife wiederholt wird. Rücken Sie Ihren Code der Lesbarkeit halber ein, aber verwenden Sie geschweifte Klammern zur Definition des Blocks.

Wiederholen, solange eine Bedingung mit while erfüllt ist

Eine while Schleife wertet ihre Boolesche Bedingung vor jeder Iteration aus. Wenn sich die Bedingung false am Anfang befindet, wird der Textkörper nie ausgeführt, sodass eine while-Schleife null oder mehrmals ausgeführt wird:

int countdown = 3;

// A while loop checks its condition before each iteration, so the body
// runs zero or more times.
while (countdown > 0)
{
    Console.WriteLine(countdown); // => 3, then 2, then 1
    countdown--;
}

Stellen Sie sicher, dass etwas in der Schleife die Bedingung ändert. Im vorherigen Beispiel countdown-- wird schließlich die Bedingung falsefestgelegt. Eine Schleife, deren Bedingung niemals zu false wird, endet nie.

Führen Sie den Textkörper mindestens einmal aus mit do-while

Eine do-while-Schleife überprüft die Bedingung nach jeder Iteration, sodass der Textkörper immer mindestens einmal ausgeführt wird. Verwenden Sie ihn, wenn der erste Durchlauf erfolgen muss, bevor Sie die Bedingung auswerten können, z. B. eingabeaufforderungen und anschließendes Validieren:

int attempts = 0;

// A do-while loop runs its body once, then checks the condition. Use it
// when the body must run at least one time.
do
{
    attempts++;
    Console.WriteLine($"Attempt {attempts}"); // => Attempt 1, then Attempt 2, then Attempt 3
}
while (attempts < 3);

Zählen mit for

Eine forSchleifenanweisung enthält drei Teile: eine Initialisierung, die einmal vor der Schleife ausgeführt wird, eine Bedingung, die vor jeder Iteration überprüft wird, und eine Iterationsanweisung, die nach jeder Iteration ausgeführt wird. Verwenden Sie for, wenn Sie den Index selbst benötigen, nicht nur die Elemente. Normalerweise benötigen Sie den Index, wenn Sie das Element ändern möchten, anstatt dessen Wert zu lesen.

// A for loop fits when you need an explicit index. The three parts are
// the initializer, the condition, and the iterator.
for (int i = 0; i < 3; i++)
{
    Console.WriteLine(i); // => 0, then 1, then 2
}

Wenn Sie nur die Elemente lesen und weder die Positionen verwenden noch neue Werte zuweisen, sollten Sie foreach bevorzugen. Sie gibt die Absicht deutlicher an und vermeidet die Indexarithmetik.

Beenden oder Überspringen mit break und continue

Mit zwei Sprunganweisungen können Sie innerhalb jeder Schleife eine feinere Steuerung vornehmen. Die break Anweisung beendet die Schleife sofort und überspringt alle verbleibenden Iterationen:

int[] numbers = [2, 4, 7, 8];

// break stops the loop immediately, skipping any remaining elements.
foreach (int number in numbers)
{
    if (number % 2 != 0)
    {
        Console.WriteLine($"First odd number: {number}"); // => First odd number: 7
        break;
    }
}

Die continue Anweisung überspringt den Rest der aktuellen Iteration und wechselt zum nächsten:

int[] values = [1, 2, 3, 4, 5];

// continue skips the rest of the current iteration and moves to the next.
foreach (int value in values)
{
    if (value % 2 == 0)
    {
        continue; // skip even numbers
    }

    Console.WriteLine(value); // => 1, then 3, then 5
}

Durchlaufen Sie einen asynchronen Stream mit await foreach

Ein asynchroner Datenstrom ist ein Reader, der eine asynchrone Aufgabe verwendet, um jedes nächste Element zu erzeugen. C# stellt es mit der IAsyncEnumerable<T> Schnittstelle dar. Daten, die im Laufe der Zeit eintreffen, z. B. Seiten aus einer Web-API oder Zeilen aus einer Datenbank, passen zu diesem Modell: Das Abrufen des nächsten Elements ist ein erwarteter Vorgang anstelle einer sofortigen Rückgabe.

Um einen asynchronen Datenstrom zu nutzen, setzen Sie das await Schlüsselwort vor foreach. Jede Iteration wartet auf das nächste Element, sodass die Schleife angehalten wird, während dieses Element erzeugt wird, anstatt den Thread zu blockieren:

private static async Task AwaitForeachExample()
{
    // await foreach consumes an asynchronous stream. Each iteration can
    // suspend while the next element is produced.
    await foreach (int value in GenerateAsync())
    {
        Console.WriteLine(value); // => 0, then 1, then 2
    }
}

private static async IAsyncEnumerable<int> GenerateAsync()
{
    for (int i = 0; i < 3; i++)
    {
        await Task.Delay(1); // stand-in for real asynchronous work
        yield return i;
    }
}

Asynchrone Streams bauen auf async und await. Eine vollständige exemplarische Vorgehensweise finden Sie unter Generieren und Nutzen asynchroner Datenströme.

Siehe auch