Каковы реальные применения доходности?

StackOverflow https://stackoverflow.com/questions/17125

  •  08-06-2019
  •  | 
  •  

Вопрос

я знаю что yield есть, и я видел несколько примеров, но не могу вспомнить о реальных приложениях. Использовали ли вы его для решения какой-то конкретной проблемы?

(В идеале какая-то проблема, которую нельзя решить другим способом)

Это было полезно?

Решение

Я понимаю, что это старый вопрос (до Джона Скита?), но я сам обдумывал этот вопрос совсем недавно.К сожалению, текущие ответы здесь (на мой взгляд) не упоминают наиболее очевидное преимущество оператора доходности.

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

Например, предположим, что у вас есть запрос к базе данных, который возвращает 1 миллион строк.Вы можете получить все строки с помощью DataReader и сохранить их в списке, поэтому для этого потребуется list_size * row_size байт памяти.

Или вы можете использовать оператор урожайности для создания итератора и хранить в памяти только одну строку за раз.По сути, это дает вам возможность обеспечить возможность «потоковой передачи» больших наборов данных.

Более того, в коде, использующем итератор, вы используете простой цикл foreach и можете при необходимости выйти из цикла.Если вы сделаете перерыв раньше, вы не принудите получить весь набор данных, когда вам нужны были только первые 5 строк (например).

Касательно:

Ideally some problem that cannot be solved some other way

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

Вот еще несколько недавних вопросов и ответов, которые дают более подробную информацию:

Добавлена ​​ценность ключевого слова в доходности?

Полезен ли выход за пределами LINQ?

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

на самом деле я использую его на своем сайте нетрадиционным способом ИдеяТруба

public override IEnumerator<T> GetEnumerator()
{
    // goes through the collection and only returns the ones that are visible for the current user
    // this is done at this level instead of the display level so that ideas do not bleed through
    // on services
    foreach (T idea in InternalCollection)
        if (idea.IsViewingAuthorized)
            yield return idea;
}

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

Одним из интересных вариантов использования является механизм асинхронного программирования, особенно для задач, которые выполняют несколько шагов и требуют одного и того же набора данных на каждом этапе.Двумя примерами этого могут быть Джеффри Рихтерс AysncEnumerator. Часть 1 и Часть 2.Среда выполнения параллелизма и координации (CCR) также использует этот метод. CCR-итераторы.

Операторы LINQ в классе Enumerable реализованы как итераторы, создаваемые с помощью оператора урожайности.Он позволяет вам связывать такие операции, как Select() и Where(), без фактического перечисления чего-либо до тех пор, пока вы фактически не используете перечислитель в цикле, обычно с помощью метода для каждого заявление.Кроме того, поскольку при вызове IEnumerator.MoveNext() вычисляется только одно значение, если вы решите остановить сбор данных в середине, вы сэкономите на производительности при вычислении всех результатов.

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

Еще одно хорошее применение доходности — выполнение функции над элементами IEnumerable и возврат результата другого типа, например:

public delegate T SomeDelegate(K obj);

public IEnumerable<T> DoActionOnList(IEnumerable<K> list, SomeDelegate action)
{
    foreach (var i in list)
        yield return action(i);
}

Использование доходности может предотвратить приведение к конкретному типу.Это удобно, чтобы гарантировать, что потребитель коллекции не будет манипулировать ею.

Вы также можете использовать yield return обрабатывать серию результатов функции как список.Например, рассмотрим компанию, которая платит своим сотрудникам каждые две недели.Используя этот код, можно получить подмножество дат расчета заработной платы в виде списка:

void Main()
{
    var StartDate = DateTime.Parse("01/01/2013");
    var EndDate = DateTime.Parse("06/30/2013");
    foreach (var d in GetPayrollDates(StartDate, EndDate)) {
        Console.WriteLine(d);
    }
}

// Calculate payroll dates in the given range.
// Assumes the first date given is a payroll date.
IEnumerable<DateTime> GetPayrollDates(DateTime startDate, DateTime endDate, int     daysInPeriod = 14) {
    var thisDate = startDate;
    while (thisDate < endDate) {
        yield return thisDate;
        thisDate = thisDate.AddDays(daysInPeriod);
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top