Предположим, у нас есть конкретный сценарий, в котором мы хотим иметь нулевое выделение памяти. Можно ли как-то использовать доходность возврата (без выделения памяти)?
public IEnumerable<int> GetValues()
{
yield return 42;
}
Например, я могу создать структуру с GetEnumerator, возвращающую структуру, и использовать ее в foreach, чтобы избежать выделения памяти:
(это возможно, потому что цикл foreach на самом деле не использует ограничение интерфейса на источник цикла. Вы можете создать класс, который будет работать с foreach без реализации ни IEnumerable, ни IEnumerable — но это тема для другого поста в блоге) https://marcinjuraszek.com/2013/10/playing-around-with-listt-part-two-ienumerable-and-ienumerablet-implementation.html
Возможно ли это как-то с возвратом доходности?
доходность доходность не выделяет. Вызов GetValues() действительно выделяет новый сгенерированный компилятором объект IEnumerable. Так что, если вы можете кэшировать это, все в порядке.





Кажется, нет, в то время как для foreach спецификации явно упоминается возможность использовать утиную печать со специальными типами:
- В противном случае определите, имеет ли тип
XсоответствующийGetEnumeratorметод: ....
Так что вы можете сотворить чудо для безраспределения foreach.
Для yeild returnтребуется особый тип возвращаемого значения:
Оператор
yieldиспользуется в блоке итератора (§13.3), чтобы передать значение объекту перечислителя (§15.14.5 ) или перечислимому объекту ( §15.14.6) итератора или сигнализировать об окончании итератора
И фактическая реализация обрабатывается компилятором (и в настоящее время это ссылочный тип, поэтому он будет выделять), и, насколько мне известно, в настоящее время нет способа перехватить/подставить его.
yield returnвсегда будет генерировать класс под капотом. Вы должны сделать это вручную через struct.