Что значит «уступить»? делать на C#?

Я видел этот синтаксис в MSDN: yield break, но не знаю, что он делает. Кто-нибудь знает?

Возврат доходности устраняет необходимость в списке поддержки, то есть вам не нужно кодировать что-то вроде MyList.Add(...), просто выполните yield return .... Если вам нужно преждевременно выйти из цикла и вернуть список виртуальных резервных копий, вы используете yield break;.

The Muffin Man 27.08.2013 01:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
526
1
154 548
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Завершает блок итератора (например, говорит, что в IEnumerable больше нет элементов).

с [+1] - хотя академически итераторов в .NET нет. только счетчики (в одном направлении, вперед.)

Shaun Wilson 13.05.2016 22:57

@Shaun Wilson, но с ключевым словом yield вы можете перебирать коллекцию в обоих направлениях, кроме того, вы можете брать каждый следующий элемент коллекции не подряд

monstr 09.03.2017 00:07

@monstr вы можете перебирать сборку любым способом, и для этого вам не нужен yield. я не говорю, что вы ошибаетесь, я понимаю, что вы предлагаете; но академически в .NET нет итераторов, только счетчики (в одном направлении, вперед) - в отличие от stdC++, в CTS / CLR нет «общей структуры итераторов». LINQ помогает закрыть пробел с помощью методов расширения, которые используют yield returnа также методы обратного вызова, но они являются первоклассными методами расширения, а не первоклассными итераторами. результирующий IEnumerable не может сам выполнять итерацию в любом направлении, кроме как вперед по отношению к вызывающему.

Shaun Wilson 10.03.2017 23:51

Сообщает итератору, что он достиг конца.

Например:

public interface INode
{
    IEnumerable<Node> GetChildren();
}

public class NodeWithTenChildren : INode
{
    private Node[] m_children = new Node[10];

    public IEnumerable<Node> GetChildren()
    {
        for( int n = 0; n < 10; ++n )
        {
            yield return m_children[ n ];
        }
    }
}

public class NodeWithNoChildren : INode
{
    public IEnumerable<Node> GetChildren()
    {
        yield break;
    }
}
Ответ принят как подходящий

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

Например, если вы определяете функцию как итератор, тело функции может выглядеть так:

for (int i = 0; i < 5; i++)
{
    yield return i;
}

Console.Out.WriteLine("You will see me");

Обратите внимание, что после того, как цикл завершит все свои циклы, будет выполнена последняя строка, и вы увидите сообщение в своем консольном приложении.

Или вот так с yield break:

int i = 0;
while (true)
{
    if (i < 5)
    {
        yield return i;
    }
    else
    {
        // note that i++ will not be executed after this
        yield break;
    }
    i++;
}

Console.Out.WriteLine("Won't see me");

В этом случае последний оператор никогда не выполняется, потому что мы преждевременно вышли из функции.

Может ли это быть просто break вместо yield break в вашем примере выше? Компилятор на это не жалуется.

orad 03.06.2014 22:26

@orad простой break в этом случае остановит цикл, но не прервет выполнение метода, таким образом, будет выполнена последняя строка и действительно будет виден текст «Не вижу меня».

Damir Zekić 04.06.2014 00:27

@ DamirZekić, завершает ли итератор все циклы в случае обрыва?

machinarium 10.07.2015 10:29

@machinarium Я не уверен, что именно вы спрашиваете, но после yield break никакой другой код в итераторе выполняться не будет, поэтому дальнейших циклов не будет.

Damir Zekić 12.07.2015 14:25

так что это когда мы не хотим условно пропускать оставшуюся доходность ...

deadManN 17.10.2015 11:28

@deadManN вы должны использовать yield break, чтобы безоговорочно пропустить оставшиеся yield return.

Damir Zekić 19.10.2015 06:59

@Damir Zekić Не могли бы вы также добавить к своему ответу, почему вы должны предпочесть перерыв в доходности возврату и в чем их отличия?

Bruno Costa 27.11.2015 23:10

@ DamirZekić возвращает null, а yield break не является то же самое. Если вы вернете значение null, вы можете получить NullReferenceException, получающий перечислитель IEnumerable, а с yield break вы этого не сделаете (есть экземпляр без элементов).

Bruno Costa 10.02.2016 16:24

@BrunoCosta Попытка получить регулярные возвраты в том же методе приводит к ошибке компилятора. Использование yield return x предупреждает компилятор, что вы хотите, чтобы этот метод был синтаксическим сахаром для создания объекта Enumerator. Этот перечислитель имеет метод MoveNext() и свойство Current. MoveNext () выполняет метод до тех пор, пока не появится оператор yield return, и преобразует это значение в Current. В следующий раз, когда вызывается MoveNext, выполнение продолжается оттуда. yield break устанавливает для Current значение null, сигнализируя о конце этого перечислителя, так что foreach (var x in myEnum()) завершится.

Wolfzoon 10.10.2016 20:23

@Wolfzoon Вместо того, чтобы видеть, что yield break устанавливает для Current значение nul, я вижу, что MoveNext возвращает false. Первый возвращает нулевое значение, второй - нет.

Bruno Costa 11.10.2016 11:23
Примечание, что для использования этого примера вы должны поместить его в функцию, например public IEnumerable<int> GetEnumerable() { ... }, а затем используйте его как foreach (var e in GetEnumerable()) { e.Dump(); }. Чтобы попробовать, см. DotNetFiddle.
Matt 14.05.2018 11:24

Означает ли это, что yield return null; такой же, как yield break;?

vipin8169 12.10.2020 03:40

yield в основном заставляет метод IEnumerable<T> вести себя аналогично кооперативному (в отличие от упреждающего) запланированному потоку.

yield return похож на поток, вызывающий функцию «расписания» или «сна», чтобы отказаться от управления процессором. Подобно потоку, метод IEnumerable<T> восстанавливает элементы управления в точке сразу после этого, при этом все локальные переменные имеют те же значения, что и до потери управления.

yield break подобен потоку, достигающему конца своей функции и завершающемуся.

Люди говорят о «конечном автомате», но конечный автомат - это на самом деле «поток». У потока есть некоторое состояние (т.е. значения локальных переменных), и каждый раз, когда он запланирован, он предпринимает некоторые действия, чтобы достичь нового состояния. Ключевым моментом в отношении yield является то, что, в отличие от потоков операционной системы, к которым мы привыкли, код, который его использует, замораживается во времени до тех пор, пока итерация не будет продвинута вручную или завершена вручную.

Здесь http://www.alteridem.net/2007/08/22/the-yield-statement-in-c/ - очень хороший пример:

public static IEnumerable<int> Range( int min, int max )
{
   while ( true )
   {
      if ( min >= max )
      {
         yield break;
      }
      yield return min++;
   }
}

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

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

Чтобы объяснить значение на примере:

    public IEnumerable<int> SampleNumbers()
    {
        int counter = 0;
        yield return counter;

        counter = counter + 2;

        yield return counter;

        counter = counter + 3;

        yield return counter ;
    }

При итерации возвращаются следующие значения: 0, 2, 5.

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

Вы не объяснили, что делает yield break

Jay Sullivan 15.03.2013 06:30

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

Sam 08.10.2013 07:33

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

Loren Paulsen 17.05.2016 00:54

Причина, по которой это плохой пример для yield break, заключается в том, что он не содержит перечислителя уровня языка, такого как foreach - при использовании перечислителя yield break предоставляет реальную ценность. этот пример выглядит как развернутый цикл. вы почти никогда не увидите этот код в реальном мире (конечно, мы все можем думать о некоторых крайних случаях), также здесь нет «итератора». «блок итератора» не может выходить за рамки метода в зависимости от языковой спецификации. то, что фактически возвращается, является «перечислимым», см. также: stackoverflow.com/questions/742497/…

Shaun Wilson 11.03.2017 00:01

Оператор yield break останавливает перечисление. Фактически, yield break завершает перечисление, не возвращая никаких дополнительных элементов.

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

IEnumerable<uint> FindPrimes(uint startAt, uint maxCount)
{
    for (var i = 0UL; i < maxCount; i++)
    {
        startAt = NextPrime(startAt);
        yield return startAt;
    }

    Debug.WriteLine("All the primes were found.");
}

В приведенном выше примере метод итератора, естественно, прекратит выполнение, как только будут найдены простые числа maxCount.

Оператор yield break - это еще один способ прекращения перечисления итератором. Это способ преждевременно выйти из перечня. Вот тот же метод, что и выше. На этот раз у метода есть ограничение на время, в течение которого он может выполняться.

IEnumerable<uint> FindPrimes(uint startAt, uint maxCount, int maxMinutes)
{
    var sw = System.Diagnostics.Stopwatch.StartNew();
    for (var i = 0UL; i < maxCount; i++)
    {
        startAt = NextPrime(startAt);
        yield return startAt;

        if (sw.Elapsed.TotalMinutes > maxMinutes)
            yield break;
    }

    Debug.WriteLine("All the primes were found.");
}

Обратите внимание на звонок yield break. Фактически, он досрочно выходит из перечисления.

Также обратите внимание, что yield break работает иначе, чем обычный break. В приведенном выше примере yield break выходит из метода без вызова Debug.WriteLine(..).

yield break - это просто способ сказать return в последний раз и не возвращать никакого значения

например

// returns 1,2,3,4,5
IEnumerable<int> CountToFive()
{
    yield return 1;
    yield return 2;
    yield return 3;
    yield return 4;
    yield return 5;
    yield break;
    yield return 6;
    yield return 7;
    yield return 8;
    yield return 9;
 }

Другие вопросы по теме