Вы можете использовать yield
для создания любого итератора. Это может быть серия с ленивой оценкой (например, чтение строк из файла или базы данных без чтения всего сразу, что может быть слишком много для хранения в памяти) или может быть повторение существующих данных, таких как List<T>
.
В C # in Depth есть бесплатная глава (6) все о блоках итераторов.
Я также недавно написал в блоге об использовании yield
для умных алгоритмы грубой силы.
Для примера ленивого чтения файлов:
static IEnumerable<string> ReadLines(string path) {
using (StreamReader reader = File.OpenText(path)) {
string line;
while ((line = reader.ReadLine()) != null) {
yield return line;
}
}
}
Это полностью «лениво»; ничего не читается, пока вы не начнете перечисление, и только одна строка всегда сохраняется в памяти.
Обратите внимание, что LINQ-to-Objects широко использует блоки итератора (yield
). Например, расширение Where
по сути:
static IEnumerable<T> Where<T>(this IEnumerable<T> data, Func<T, bool> predicate) {
foreach (T item in data) {
if (predicate(item)) yield return item;
}
}
И снова полностью ленивый - позволяет объединить несколько операций в цепочку, не заставляя все загружать в память.
person
Marc Gravell
schedule
21.12.2008