考虑这个片段(比原始代码简化得多):
async IAsyncEnumerable<(DateTime, double)> GetSamplesAsync()
{
// ...
var cbpool = new CallbackPool(
HandleBool: (dt, b) => { },
HandleDouble: (dt, d) =>
{
yield return (dt, d); //not allowed
});
while (await cursor.MoveNextAsync(token))
{
this.Parse(cursor.Current, cbpool);
}
}
private record CallbackPool(
Action<DateTime, bool> HandleBool,
Action<DateTime, double> HandleDouble
);
然后,以下Parse
只是原始行为的等效行为。
Random _rnd = new Random();
void Parse(object cursor, CallbackPool cbpool)
{
double d = this._rnd.NextDouble(); //d = [0..1)
if (d >= 0.5)
{
cbpool.HandleDouble(new DateTime(), d);
}
else if (d >= 0.25)
{
cbpool.HandleBool(new DateTime(), d >= 0.4);
}
}
但是,我确实喜欢GetSamplesAsync
代码,但编译器不喜欢:yield
不能在 lambda 中使用。
所以,我改变了函数如下,虽然它变得更不可读(而且也容易出错):
async IAsyncEnumerable<(DateTime, double)> GetSamplesAsync()
{
// ...
(DateTime, double) pair = default;
bool flag = false;
var cbpool = new CallbackPool(
HandleBool: (dt, b) => { },
HandleDouble: (dt, d) =>
{
pair = (dt, d);
flag = true;
});
while (await cursor.MoveNextAsync(token))
{
this.Parse(cursor.Current, cbpool);
if (flag)
{
yield return pair;
}
flag = false;
}
}
我想知道是否有更好的方法来解决这种模式。