Metodi iteratori con yield return
Generi sequenze un elemento alla volta.
Metodi iteratori con yield return è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
Che cos'è un metodo iteratore
Un metodo iteratore produce una sequenza di valori, uno alla volta, usando yield return. Il compilatore lo trasforma in una macchina a stati, quindi non è necessario creare e gestire autonomamente un elenco.
Il primo yield return
Ogni yield return restituisce un valore al chiamante e mette in pausa il metodo. L'esecuzione riprende subito dopo quell'istruzione nell'iterazione successiva.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> FirstThree()
{
yield return 1;
yield return 2;
yield return 3;
}
public static void Main()
{
foreach (var n in FirstThree())
Console.WriteLine(n);
}
}yield return all'interno di un ciclo
La maggior parte degli iteratori produce valori all'interno di un ciclo. Qui si generano i primi count numeri pari senza allocare alcuna raccolta.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> Evens(int count)
{
for (int i = 0; i < count; i++)
yield return i * 2;
}
public static void Main()
{
foreach (var n in Evens(5))
Console.WriteLine(n);
}
}Il metodo restituisce IEnumerable
Un metodo iteratore deve restituire IEnumerable<T> o IEnumerator<T>, oppure le versioni non generiche. Non si scrive mai return con un valore; si usa soltanto yield return.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<string> Greetings()
{
yield return "hello";
yield return "hi";
yield return "hey";
}
public static void Main()
{
foreach (var g in Greetings())
Console.WriteLine(g);
}
}L'esecuzione viene sospesa e ripresa
Lo stato tra un yield e l'altro viene conservato automaticamente. Le variabili locali mantengono i propri valori durante le pause, rendendo molto semplice generare totali progressivi.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> RunningTotal(IEnumerable<int> nums)
{
int total = 0;
foreach (var n in nums)
{
total += n;
yield return total;
}
}
public static void Main()
{
foreach (var t in RunningTotal(new[] { 1, 2, 3, 4 }))
Console.WriteLine(t);
}
}Generare sequenze infinite
Poiché i valori vengono prodotti su richiesta, un iteratore può descrivere in modo sicuro una sequenza infinita. È il chiamante a decidere quando smettere di richiedere valori.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> Naturals()
{
int i = 1;
while (true) yield return i++;
}
public static void Main()
{
int taken = 0;
foreach (var n in Naturals())
{
Console.WriteLine(n);
if (++taken == 5) break;
}
}
}Trasformare una sequenza di input
Gli iteratori sono ideali per creare pipeline: leggono gli elementi da una sequenza, li trasformano e restituiscono i risultati in modo differito.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<string> Labelled(IEnumerable<int> nums)
{
foreach (var n in nums)
yield return "item-" + n;
}
public static void Main()
{
foreach (var s in Labelled(new[] { 10, 20, 30 }))
Console.WriteLine(s);
}
}Filtrare con gli iteratori
Per filtrare, è sufficiente restituire solo gli elementi desiderati. Gli elementi ignorati non vengono mai prodotti, quindi il codice a valle non li vede.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> OnlyPositive(IEnumerable<int> nums)
{
foreach (var n in nums)
if (n > 0) yield return n;
}
public static void Main()
{
foreach (var n in OnlyPositive(new[] { -2, 5, -1, 8 }))
Console.WriteLine(n);
}
}Il compilatore crea una macchina a stati
Dietro le quinte, il compilatore riscrive l'iteratore trasformandolo in una classe che implementa IEnumerator<T>, tenendo traccia di un campo di stato nascosto e di un valore Current. Tutto questo meccanismo è disponibile automaticamente.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<char> Letters()
{
yield return 'a';
yield return 'b';
yield return 'c';
}
public static void Main()
{
IEnumerator<char> e = Letters().GetEnumerator();
while (e.MoveNext())
Console.WriteLine(e.Current);
}
}Comporre più iteratori
Gli iteratori si concatenano naturalmente perché ciascuno restituisce un IEnumerable<T>. Si può passare l'output di un iteratore a quello successivo per creare pipeline leggibili.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<int> Range(int start, int count)
{
for (int i = 0; i < count; i++) yield return start + i;
}
static IEnumerable<int> Squares(IEnumerable<int> nums)
{
foreach (var n in nums) yield return n * n;
}
public static void Main()
{
foreach (var n in Squares(Range(1, 4)))
Console.WriteLine(n);
}
}Provi personalmente
Scriva un iteratore che raggruppi una sequenza di input in blocchi di dimensione fissa. Restituisce liste su richiesta e mostra quanta logica può essere contenuta in un singolo iteratore ben strutturato.
using System;
using System.Collections.Generic;
public class Program
{
static IEnumerable<List<int>> Batch(IEnumerable<int> source, int size)
{
var bucket = new List<int>();
foreach (var n in source)
{
bucket.Add(n);
if (bucket.Count == size) { yield return bucket; bucket = new List<int>(); }
}
if (bucket.Count > 0) yield return bucket;
}
public static void Main()
{
foreach (var group in Batch(new[] { 1, 2, 3, 4, 5 }, 2))
Console.WriteLine(string.Join(",", group));
}
}Verifica rapida
Richiami il funzionamento dei metodi iteratori.
Riepilogo
I metodi iteratori usano yield return per produrre sequenze su richiesta.
- Il metodo restituisce
IEnumerable<T>oIEnumerator<T>. - Ogni
yield returnemette un valore e mette in pausa l'esecuzione, preservando lo stato locale. - Possono descrivere in modo sicuro sequenze infinite.
- Il compilatore genera automaticamente la macchina a stati.
Domande Frequenti
La lezione «Metodi iteratori con yield return» è gratuita?
Sì — il testo completo di «Metodi iteratori con yield return» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Metodi iteratori con yield return»?
Generi sequenze un elemento alla volta. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Metodi iteratori con yield return»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Metodi iteratori con yield return
- yield break e terminazione anticipata
- Semantica della valutazione lazy
- Enumerabili personalizzati