Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Pokud chcete vrátit sekvenci, jejíž prvky volající můžou postupně využívat, vyberte iterátor, aniž byste nejprve vytvářeli úplný výsledek v kolekci. Tento přístup odpovídá vygenerovaným hodnotám, filtrům s vlastním tokem řízení a sekvencí, které volající můžou přestat číst dříve. Ve srovnání s dokončenou kolekcí se iterátor změní, když k práci dojde, a ne jenom to, jak ji napíšete.
Tip
V tomto článku se naučíte synchronní iterátory pro vývojáře, kteří znají metody, smyčky a kolekce. Kompletní yield syntaxi a omezení najdete v referenčních informacích kyield příkazu.
Metoda iterátoru vytvoří sekvenci hodnot po jednom. Tento článek se zaměřuje na metody iterátoru, které vracejí IEnumerable<T>, jejichž hodnoty volající obvykle spotřebovávají s příkazem foreach .
Vytváření prvků pomocí yield return
Slouží yield return k zadání dalšího prvku v sekvenci. Následující iterátor vybere přijatelné hodnoty teploty ze senzoru. V tomto scénáři -1 označí konec dat snímače.
int[] readings = [21, 27, 24, -1, 19];
IEnumerable<int> acceptedReadings =
SelectTemperatures(readings, maximum: 25);
Console.WriteLine("Sequence created.");
foreach (int temperature in acceptedReadings)
{
Console.WriteLine($"Accepted: {temperature}°C");
}
static IEnumerable<int> SelectTemperatures(
IEnumerable<int> readings,
int maximum)
{
foreach (int reading in readings)
{
Console.WriteLine($"Checking {reading}°C");
if (reading == -1)
{
yield break;
}
if (reading <= maximum)
{
yield return reading;
}
}
}
SelectTemperatures vrátí IEnumerable<int>hodnotu , která představuje sekvenci int hodnot. Každá z nich yield return reading poskytuje jednu hodnotu smyčky foreach . Jakmile volající zpracuje danou hodnotu, iterátor pokračuje dalším vstupem.
Pro většinu moderního kódu jazyka C# použijte obecný IEnumerable<T> formulář. Argument typu, například int, říká volajícím, který typ prvku sekvence obsahuje.
Ukončit sekvenci pomocí yield break
Slouží yield break k ukončení iterátoru před tím, než ovládací prvek dosáhne konce metody. V tomto příkladu hodnota -1 sentinelu znamená, že nejsou k dispozici žádné další čtení:
if (reading == -1)
{
yield break;
}
Iterátor také končí přirozeně, když provádění dosáhne konce jeho těla. Použijte yield break , když by podmínka měla okamžitě zastavit produkční prvek.
Využití iterátoru s foreach
Iterátor zveřejňuje stejný IEnumerable<T> obrazec jako mnoho .NET kolekcí. Volající můžou používat foreach bez znalosti toho, jak sekvence vytváří její prvky:
foreach (int temperature in SelectTemperatures(readings, 25))
{
Console.WriteLine($"Accepted: {temperature}°C");
}
Volající požádá o každý prvek při přechodu smyčky. Iterátor udržuje svou pozici mezi požadavky a pokračuje po předchozím yield return.
Vysvětlení odloženého prvku v produkčním prostředí
Volání metody iterátoru nespustí jeho tělo okamžitě. Metoda začne vytvářet prvky, když volající začne výčtu. Toto chování se nazývá odložené spuštění.
Příklad se vytiskne před všemi Checking ... zprávamiSequence created.. Iterátor začne kontrolovat čtení pouze v případě, že foreach smyčka požádá o první prvek.
Odložené provádění má praktické účinky:
- Volající může zahájit zpracování před tím, než iterátor vytvoří každý prvek.
- Iterátor může přestat brzy s
yield break. - Volající, který nikdy nevyčísluje sekvenci, nespustí tělo iterátoru.
- Každý nový výčet znovu spustí iterátor.
V účelu a dokumentaci metody zrušte odložené spuštění. Čtenáři nemohou odvodit časování provádění samostatně, IEnumerable<T> protože iterátory i kolekce můžou toto rozhraní vystavit. Udržujte výrobu prvků bez nesouvisejících vedlejších účinků, protože volající mohou vytvořit výčet sekvence později nebo vícekrát. Toto načasování ilustruje diagnostické zprávy příkladu.
Volba iterátoru nebo kolekce
Vrátí iterátor, když hodnoty přirozeně přicházejí po jednom nebo když volající nepotřebuje úplný výsledek okamžitě. Vrátí dokončenou kolekci, když volající potřebují stabilní snímek, indexovaný přístup nebo opakovaný výčet bez přepočítání prvků.
Oba přístupy můžou vrátit stejné prvky. Iterátor ponechá výrobu prvku pod kontrolou volajícího; Metoda, která sestaví kolekci, dokončí, než se vrátí.
Pokud chcete provést akci pro každou položku bez vrácení sekvence, použijte běžnou smyčku. U standardního filtru nebo transformace upřednostňujte operaci LINQ, jako Where je nebo Select; napište iterátor, pokud je vlastní logika pro výrobu elementů jasnější jako řada příkazů.
Metody iterátoru se skládají z LINQ, protože oba používají IEnumerable<T>. Volající může například přidat další filtr:
var comfortableReadings = SelectTemperatures(readings, 25)
.Where(static temperature => temperature >= 18);
Iterátor a operace LINQ zůstávají odložené, dokud se nevyčtou comfortableReadingskód .
Asynchronní sekvence najdete v tématu Generování a využívání asynchronních datových proudů. Pro vlastní vzory výčtu a všechna yield omezení použijte odkaz na jazyk.