Próbuję lepiej zrozumieć słowo "yield" i myślę, że mam wystarczająco dobre zrozumienie tego, więc przeprowadziłem testy, ale byłem zaskoczony wynikami.Zrozumienie słowa kluczowego yield i LINQ
Jeśli uruchomić poniższy kod otrzymuję następujący wynik, który pokazuje, że pętle w całym zakresie nie tylko do numeru 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;
}
}
}
wyjściowa:
Method Call
LINQ
Start result loop
Found 2
Found 4
Item is 4
Found 6
Found 8
Found 10
Jeśli Uruchomiłem poniższy kod, który pokazuje, że dociera tylko do 4, a następnie zatrzymuje się.
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;
}
}
}
wyjściowa:
Method Call
Start result loop
Found 2
Found 4
Item is 4
Chyba nie jestem understading coś ale wygląda jakby LINQ robi przeciwieństwo tego, czego od niego oczekujesz? Chociaż LINQ wykorzystywał również wydajność i odraczanie wykonania, i oczekiwałbym, że wyniki z drugiego zestawu kodów będą takie same dla pierwszego zestawu kodu.
'Gdzie" filtruje wyniki, nie zatrzymuje wyników zwracanych, gdy element spełnia predykat. Z drugiej strony twoja ręczna pętla 'foreach' zrywa się, gdy predykat jest spełniony ... –