Сведения о вопросе

HEIGTH

06:08, 28th August, 2020

Теги

c#   .net   yield    

Каковы реальные применения yield в реальной жизни?

Просмотров: 442   Ответов: 7

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

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



  Сведения об ответе

+-*/

07:09, 1st August, 2020

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

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

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

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

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

Относительно:

Ideally some problem that cannot be solved some other way

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

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

Добавленная стоимость ключевого слова Yield?

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


  Сведения об ответе

park

11:54, 19th August, 2020

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

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 час.


  Сведения об ответе

crush

23:27, 19th August, 2020

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


  Сведения об ответе

piter

17:23, 25th August, 2020

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


  Сведения об ответе

park

04:42, 8th August, 2020

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

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


  Сведения об ответе

FAriza

12:53, 18th August, 2020

Еще одно хорошее применение yield - это выполнение функции на элементах 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);
}


  Сведения об ответе

lesha

08:03, 10th August, 2020

Можно также использовать 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);
    }
}


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться