Het is niet while vs foreach dat maakt het verschil. Het is de aanroep van .Cast<T>() .
In het eerste voorbeeld levert u op voor dezelfde object in elke iteratie van de while-lus. Als u niet oppast, heeft u uiteindelijk de opbrengstiterator voltooid voordat u de gegevens daadwerkelijk gebruikt, en is de DataReader al verwijderd. Dit kan gebeuren als u bijvoorbeeld .ToList() . zou aanroepen na het aanroepen van deze methode. Het beste waar je op kunt hopen, is dat elk record in de lijst dezelfde waarde heeft.
(Pro-tip:meestal wil je .ToList() totdat het absoluut moet. Het is beter om gewoon met IEnumerable records te werken).
In het tweede voorbeeld, wanneer u .Cast<T>() . aanroept op de datareader maakt u in feite een kopie van de gegevens terwijl deze door elk record worden herhaald. Nu levert u niet langer hetzelfde object op.