Sto cercando di capire meglio la parola chiave yield e penso di averne una conoscenza abbastanza decente, quindi ho eseguito alcuni test, ma sono stato sorpreso dai risultati.Capire la parola chiave yield e LINQ
Se eseguo il codice qui sotto ottengo il seguente output che dimostra che loop su tutto il campo, non solo fino al numero 4.
public void DoIt()
{
Console.WriteLine("Method Call");
var results = GetData(Enumerable.Range(1, 10));
Console.WriteLine("LINQ");
var filtered = results.Where(x => x == 4);
Console.WriteLine("Start result loop");
foreach (var item in filtered)
{
Console.WriteLine("Item is " + item);
}
}
private IEnumerable<int> GetData(IEnumerable<int> Input)
{
foreach (int item in Input)
{
if (item % 2 == 0)
{
Console.WriteLine("Found " + item);
yield return item;
}
}
}
uscita:
Method Call
LINQ
Start result loop
Found 2
Found 4
Item is 4
Found 6
Found 8
Found 10
Se Corro il codice qui sotto mostra che arriva solo a 4 e poi si ferma.
public void DoIt()
{
Console.WriteLine("Method Call");
var results = GetData(Enumerable.Range(1, 10));
Console.WriteLine("Start result loop");
foreach (var item in results)
{
if (item == 4)
{
Console.WriteLine("Item is " + item);
break;
}
}
}
private IEnumerable<int> GetData(IEnumerable<int> Input)
{
foreach (int item in Input)
{
if (item % 2 == 0)
{
Console.WriteLine("Found " + item);
yield return item;
}
}
}
uscita:
Method Call
Start result loop
Found 2
Found 4
Item is 4
Credo che non sto understading qualcosa, ma sembra come se LINQ sta facendo il contrario di quello che mi aspetto che faccia? Anche se LINQ ha utilizzato anche la resa e l'esecuzione posticipata e mi aspetto che i risultati del secondo set di codice siano gli stessi per il primo set di codice.
'Where' filtra i risultati, non smette di restituire risultati quando un oggetto soddisfa il predicato. D'altra parte, il ciclo manuale 'foreach' si interrompe quando il predicato è soddisfatto ... –