public static {ReturnType} GetNums()
{
var number = 0;
while (true)
{
if (number > 5)
yield break;
yield return number++;
}
}
a) void
b) IEnumerable<int>
c) List<int>
d) int
e) object
Розгорнути правильну відповідь з поясненням
Наведений метод використовує два спеціальних ключових слова yield break
та yield return
. Метод, у якому використовуються такі конструкції, називається ітератором.
Ітератор може бути іменованим (як у нашому випадку), так і не іменованим. Не іменований ітератор оголошується для класу за допомогою визначення методу GetEnumerator(). У цьому випадку єкземпляри такого класу можна напряму використовувати у foreach чи для linq операцій.
Відмінність ітератора від звичайного метода полягає у тому, що метод повертає єдине значення за допомогою return, а ітератор – декілька (або взагалі жодного). Ітератор повернить стільки значень, скільки викликано yield return
. Виклик yield return
можно написати декілька разів поспіль або, як у завданні, використати цикл. Ключове слово yield break
означає що більше елементів повертати не потрібно, навіть якщо далі слідують іще конструкції yield return
. Зупинка ітератора з використанням yield break
не є обов'язковою. Наприклад ми можемо переписати код із завдання так:
while (number < 5)
{
yield return number++;
}
Також цікавим є перехоплення помилок у ітераторі. Ключове слово yield
не можна використовувати всередині try-catch блоку. Натомість потрібно спочатку отримати значення для повернення, а вже потім викликати yield
наприклад:
foreach (var item in data)
{
try
{
result = PrepareData(item);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex.Message);
continue;
}
yield return result;
}
У попередньому абзаці вже згадувалося де можна використати результат, шо повертає ітератор – у конструкції foreach та для linq операцій. А отже значення, що повертає ітератор, має бути інтерфейсом IEnumerable. Типізація ж для IEnumerable має відповідати саме тому типу, що повертає yield return
. У нашому випадку це IEnumerable<int>.
Правильна відповідь: a) IEnumerable