Какая польза от выхода?

Возможный дубликат:
Что делает "yield break;" в С#?

Может ли кто-нибудь увидеть использование для оператора "break break", которого иначе не удалось бы достичь, используя "break" или "return".

Это утверждение кажется совершенно бесполезным. Что еще, без этого утверждения, выражение "yield return X" могло бы быть упрощено для "yield X", что намного читаемо.

Что мне не хватает?

Ответ 1

Чтобы привести пример кода, скажем, вы хотите написать итератор, который ничего не возвращает, если источник пуст или пуст.

public IEnumerable<T> EnumerateThroughNull<T>(IEnumerable<T> source)
{
    if (source == null)
        yield break;

    foreach (T item in source)
        yield return item;
}

Без разрыва выхода становится невозможным вернуть пустое множество внутри итератора.

Ответ 2

yield break указывает, что метод должен прекратить возвращать результаты. "возврат" сам по себе не будет достаточно хорошим или может привести к ошибке, потому что возвращаемый тип метода должен быть IEnumerable.

Я не уверен, почему ключевое слово return также необходимо. Мое лучшее предположение было бы в том, что это помогает сделать намерение заявления немного яснее.

Если вас это интересует, в этой статье объясняется, какая доходность за кадром

За кулисами ключевого слова С# yield

Ответ 3

выход и разрыв делают совершенно разные вещи! Смотри

for(int i = 0; i < 10; ++i) {
   if(i > 5) { break; }
   yield return i;
}

for(int v = 2710; v < 2714; v+=2) {
   yield return v;
}

for(int s = 16; s < 147; ++s) {
   if(s == 27) { yield break; }
   else if(s > 17) { yield return s; }
}

Выход был бы IEnumerable этих значений: 0, 1, 2, 3, 4, 5, 2710, 2712, 18, 19, 20, 21, 22, 23, 24, 25, 26

Вот какой-то метод, который не приносит ничего полезного, но он иллюстрирует, что вы можете комбинировать разрыв производительности и разбить на один и тот же метод, и они делают две разные вещи! Разрыв просто вырывается из цикла, выходный разрыв заканчивает метод полностью.

Я предполагаю, что причина возврата не используется, потому что вы не возвращаете IEnumerable себя в метод. Кроме того, разве вы не считаете, что разрыв в доходности яснее возврата, для такого рода итеративной ситуации? Я лично делаю.

Ответ 4

Нельзя использовать инструкцию return в блоке итератора. Более того, оператор break может выполнять двойную задачу внутри блока итератора, если ему разрешено влиять на итерацию: его можно использовать для выхода из цикла или из коммутатора и его можно использовать для разрыва из всей итерации.

yield return и yield break и являются двумя ключевыми словами сами по себе, и оба они кажутся необходимыми.

Ответ 5

Оператор

return используется для возврата значения из функции.

Если у вас есть итераторная функция:

public IEnumerable<int> IteratorOverInt() { }

оператор возврата в приведенной выше функции должен будет вернуть заполненный IEnumerable<int>.

public IEnumerable<int> IteratorOverInt() {
    return new List<int> { 1, 2, 3, 4 };
}

но если вы работаете над функцией итератора, вы будете использовать yield return, поэтому ваш код может выглядеть так:

public IEnumerable<int> IteratorOverInt() {
    for (int i = 0; i < 4; i++) {
        yield return i;
    }
}

Итак, yield return возвращает int, а подпись метода требует IEnumerable<int>

Что сделал бы оператор return в приведенном выше случае? Возвратные результаты переопределяют доходность? Конкатенировать все с урожаем? return не имеет большого смысла в приведенном выше случае.

Таким образом, нам нужен способ return, который имеет смысл в блоке итератора, поэтому существует yield break.

Конечно, вы можете сделать это с помощью break, но тогда как вы выйдете из тела функции, если у вас будет больше кода, который будет выполняться? Оберните все в сложный блок if-else? Я бы сказал, что лучше было бы yield break.

Ответ 6

Вам нужно иметь различие между возвратом реализации IEnumerable, которая уже существует (возможно, вы собираетесь вернуть List) и анонимным итератором.

Вы не можете просто использовать return или break, потому что это допустимые ключевые слова, которые могут использоваться для других целей. Вы также не можете использовать доход по своему усмотрению, потому что вам необходимо указать, возвращаете ли вы элемент в перечислении или завершаете перечисление, следовательно, необходимо возвращать доходность и разрыв доходности.