yield оператор в async методе без IAsyncEnumerable

Как мне возвращать значение через yield в асинхронном методе БЕЗ использования IAsyncEnumerable?

public async Task<IEnumerable<MyClass>> MyEnumerableMethod()
{
   foreach(var item in smthCollection)
   {
      yield return item; //CS1624 Task<IEnumerable<MyClass>> is not an iterator interface type
   }
}

Ответы (3 шт):

Автор решения: aepot

Есть 2 варианта использования итератора, позволяющие применять ключевое слово yield:

Синхронный

IEnumerable<T>
IEnumerator<T>

И асинхронный

async IAsyncEnumerable<T>
async IAsyncEnumerator<T>

Больше никаких вариантов сигнатур нет, это ограничение зашито на уровне языка C#.

→ Ссылка
Автор решения: Exploding Kitten

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

async Task<IEnumerable<int>> Test()
{
    var smthCollection = await GetSmth();
    
    return Get(smthCollection);
    
    IEnumerable<int> Get(IEnumerable<int> smthCollection)
    {
        foreach(var item in smthCollection)
        {
            // что-то делаем с item
            yield return item; 
        }
    }
}

Но тогда у лучше использовать IAsyncEnumerable<T>. А так да, я согласен, что использовать async и yield без IAsyncEnumerable<T> нельзя.

→ Ссылка
Автор решения: CrazyElf

Проблема в том, что Task<IEnumerable<MyClass>> должен возвращать одну задачу, внутри которой завёрнут IEnumerable (и один из ответов показывает, как это можно сделать). Когда используется return, то C# сам оборачивает возвращаемое значение в Task, а что вы хотите обернуть в Task, когда делаете yield return, компилятору непонятно - это должно быть много Task-ов или что? Поэтому так нельзя.

→ Ссылка