Iterációs utasítások

Jótanács

Ez a cikk az Alapismeretek szakasz része azon fejlesztők számára, akik már legalább egy programozási nyelvet ismernek, és c#-t tanulnak. Ha még csak most ismerkedik a programozással, először az Első lépések oktatóanyagokkal kezdje. A teljes szintaxisért tekintse meg a nyelvi referencia iterációs utasításait .

Más nyelvről jön? Mind a négy C#-ciklus (foreach, ,whiledo-while és for) közvetlen megfelelőkkel rendelkezik Java, C++ és JavaScript nyelven. Leggyakrabban használja foreach . Index használata nélkül iterál végig egy gyűjteményen, akárcsak a Java továbbfejlesztett for vagy a JavaScript for...of esetében.

Az iterációs utasítások ismétlődően futtatnak egy kódblokkot. A blokkon való minden egyes áthaladás egy iteráció, az ismétlődő blokk pedig egy ciklus. A C# négy hurkot biztosít. Kezdje a foreach gyűjteményekkel, használja while ésdo-whileamikor egy feltétel szabályozza az ismétlődést, és használjafor, amikor explicit indexre van szüksége.

Gyűjtemény iterálása a foreach

Az foreach utasítás a gyűjtemény minden eleméhez egyszer futtatja a törzsét, sorrendben. Ez a leggyakoribb választás a gyűjtemények olvasásához, mivel nem kezel indexet vagy korlátellenőrzést. Az foreach utasítás megakadályozza a tipikus, egyenként előforduló hibákat:

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 Minden olyan típussal működik, amelyet a C# szekvenciaként ismer fel, beleértve a tömböket List<T>és Dictionary<TKey,TValue>a . Az iterációs változó (name az előző példában) csak olvasható, így a cikluson belül nem lehet újra értéket adni neki.

A ciklus törzse egyetlen utasítás, például egy hozzárendelés vagy metódushívás. A blokkutasítás önmagában egy olyan utasítás, amely nulla vagy több utasítást tartalmaz kapcsos zárójelekben ({ }).

Számos kódolási szabvány azt javasolja, hogy a hurok törzsét tegye kapcsos zárójelek közé, még akkor is, ha az csak egyetlen utasításból áll. A kapcsos zárójelek explicité teszik a hatókört. Ez megakadályoz egy gyakori hibát: egy később hozzáadott második sor esetében azt várja, hogy minden iterációban lefusson, ehelyett azonban csak egyszer fut le, a ciklus után. Csak a kapcsos zárójelek határozzák meg, hogy mely utasítások tartoznak a ciklushoz. A C# nem tekinti jelentőségtelinek az üres helyeket, ezért önmagában a behúzásnak sincs jelentősége. A kapcsos zárójelek egyetlen sor körül is érvényesek: a blokk az az egyetlen utasítás, amelyet a ciklus ismétel. Húzza be a kódot az olvashatóság érdekében, de a blokk meghatározásához a kapcsos zárójelekre hagyatkozzon.

Ismétlés, amíg egy feltétel teljesül while

Egy while ciklus minden egyes iteráció előtt ellenőrzi a logikai feltételt. Ha a feltétel kezdetben false, a törzs egyáltalán nem hajtódik végre, így a while ciklus nullaszor vagy többször hajtódik végre:

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--;
}

Győződjön meg arról, hogy a cikluson belül valami módosítja a feltételt. Az előző példában countdown-- végül a feltételt falseadja meg. Az a ciklus, amelynek feltétele soha nem lesz false, örökké fut.

Hajtsa végre a törzset legalább egyszer a(z) do-while használatával.

A do-while ciklus minden iteráció után ellenőrzi annak állapotát, így a törzs mindig legalább egyszer fut. Akkor használja, amikor az első lépésnek meg kell történnie, mielőtt kiértékelheti a feltételt, például be kell kérnie a bemenetet, majd érvényesítenie kell:

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);

Számoljon ezzel: for

A for ciklusutasítás három részből áll: egy inicializálóból , amely egyszer fut a ciklus előtt , egy feltételt, amelyet minden iteráció előtt ellenőriztek, és egy iterátort , amely az egyes iterációk után fut. Akkor használja for , ha magát az indexet kell használnia, nem csak az elemeket. Általában akkor van szüksége az indexre, ha az elem értékét szeretné módosítani az érték olvasása helyett.

// 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
}

Ha csak az elemeket olvassa el, ha nem használja a pozíciókat, vagy nem rendel hozzá új értékeket, válassza a kívánt foreachértéket. A szándékot egyértelműbben állítja be, és elkerüli az index aritmetikai használatát.

Kilépés vagy kihagyás ezzel: break és continue

Két ugrási utasítás minden hurokon belül finomabb vezérlést biztosít. Az break utasítás azonnal kilép a ciklusból, és kihagyja a fennmaradó iterációkat:

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;
    }
}

Az continue utasítás kihagyja az aktuális iteráció többi részét, és továbblép a következőre:

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
}

Aszinkron stream bejárása a(z) await foreach használatával

Az aszinkron adatfolyam egy olyan folyamolvasó, amely minden következő elem előállítására aszinkron feladatot használ. A C# a IAsyncEnumerable<T> interfésszel ábrázolja. Az idővel érkező adatok, például a webes API-ból származó lapok vagy egy adatbázis sorai megfelelnek ennek a modellnek: a következő elem beolvasása egy várandós művelet, nem pedig azonnali visszatérés.

Aszinkron adatfolyam használatához tegye a await kulcsszót a(z) foreach elé. Minden iteráció várja a következő elemet, így a hurok felfüggeszti az adott elem előállítását a szál blokkolása helyett:

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;
    }
}

Az aszinkron adatfolyamok a(z) async és await elemekre épülnek. A teljes útmutatót az aszinkron streamek létrehozása és felhasználása című témakörben találja.

Lásd még