yield return
в C# используется для создания итераторов, которые позволяют лениво (по мере необходимости) возвращать элементы последовательности. Это делает код более эффективным по памяти и удобным для работы с большими наборами данных.
🔹 Как работает yield return
- Метод, использующий
yield return
, становится итераторным методом, который возвращаетIEnumerable<T>
илиIEnumerator<T>
. - При первом вызове
MoveNext()
выполнение метода начинается и продолжается доyield return
, после чего выполнение приостанавливается, а значение возвращается. - При следующем вызове
MoveNext()
выполнение метода продолжается с того же места, где оно было приостановлено. - Когда выполнение метода доходит до
yield break
, или метод заканчивается, итератор завершается.
🔹 Простой пример использования yield return
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
foreach (var num in GetNumbers())
{
Console.WriteLine(num);
}
}
static IEnumerable<int> GetNumbers()
{
yield return 1;
yield return 2;
yield return 3;
}
}
🔹 Вывод в консоль:
1
2
3
Как это работает:
foreach
вызываетMoveNext()
, выполнение доходит доyield return 1
, возвращается1
, а выполнение приостанавливается.- При следующем
MoveNext()
выполнение продолжается со следующей строки (yield return 2
). - Процесс продолжается, пока не будет достигнут конец метода.
🔹 Использование yield break
Иногда нужно прервать генерацию последовательности, например:
static IEnumerable<int> GetNumbers()
{
yield return 1;
yield return 2;
yield break; // Прерываем итерацию, дальше код не выполняется
yield return 3; // Никогда не выполнится
}
🔹 Вывод в консоль:
1
2
🔹 Пример с yield return
и for
static IEnumerable<int> Range(int start, int count)
{
for (int i = 0; i < count; i++)
{
yield return start + i;
}
}
static void Main()
{
foreach (var num in Range(10, 5))
{
Console.WriteLine(num);
}
}
🔹 Вывод:
10
11
12
13
14
🔹 yield return
vs return
Особенность | yield return | return |
---|---|---|
Возвращает значение | Да | Да |
Возвращает сразу все значения | Нет (по одному, лениво) | Да |
Можно использовать в IEnumerable<T> | Да | Нет |
Запоминает состояние метода | Да | Нет |
Пример с return
:
static List<int> GetNumbers()
{
return new List<int> { 1, 2, 3 };
}
Здесь метод возвращает всю коллекцию сразу, что неэффективно для больших данных.
🔹 Когда использовать yield return
✅ Когда элементы генерируются на лету, без необходимости загружать всю коллекцию в память.
✅ Когда последовательность может быть бесконечной (например, генератор случайных чисел).
✅ Когда метод должен сохранять состояние между вызовами.
🔹 Заключение
yield return
делает код более эффективным и удобным, особенно при работе с большими данными. Он лениво генерирует элементы последовательности по мере необходимости, а также сохраняет состояние метода между вызовами.
Добавить комментарий