在 JavaScript 中,我们有
yield
运算符,它能够通过 next()
方法返回可选地提供给生成器的值。从下一个:
参数
可选value
要发送到生成器的值。该值将作为
表达式的结果进行分配。例如,在yield
中,传递给variable = yield expression
函数的值将被分配给.next()
。variable
和产量:
返回值
返回传递给生成器的
方法以恢复其执行的可选值。next()
在 C# 中,我理解
Generator.prototype.next()
大致相当于 IEnumerator.MoveNext()
。然而,虽然 next()
采用可选的 value
参数,但 MoveNext()
中似乎没有任何等效参数。
我真的很想要某种能够将值传递给 C# 迭代器的方法,就像我可以将值传递给 JavaScript 生成器一样。我想我也许可以尝试使用通道等,但我希望利用 C# 自己的
yield
运算符提供的语法糖。有谁知道这是否可能?
好吧,在摆弄了一些之后,这是一个答案的粗略开始。它大致基于这个示例。
namespace Coroutine
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
internal class Program
{
static void Main(string[] args)
{
var point = new Point(1, 2, 3);
foreach (var coordinate in point)
{
Console.Write(coordinate);
Console.Write(" ");
point.Arg = coordinate;
}
// Output: 1 3 6
}
public class Point
{
public Point(int X, int Y, int Z)
{
this.X = X;
this.Y = Y;
this.Z = Z;
this.Arg = 0;
}
public int X { get; }
public int Y { get; }
public int Z { get; }
public object Arg { get; set; }
public IEnumerator<int> GetEnumerator()
{
yield return X + (int)Arg;
yield return Y + (int)Arg;
yield return Z + (int)Arg;
}
}
}
}
有点难看,但我想经过一些清理后这可能会起作用。
基本上代替调用
move(value)
,我在 Arg
调用 foreach
之前设置 MoveNext()
。我有 variable = yield expression;
来代替 yield expression; variable = Arg;
。
测试的要点是验证我实际上可以将数据传递到迭代器中,例如从外部调用者修改迭代器的行为。这种方法仍然使用了一些
foreach/yield
语法,即不手动重新创建编译器生成的迭代器状态机。
希望这对有同样问题的人有用,并很高兴听到您可能有的任何其他想法。我想我会在实际生产中使用它之前清理它,也许添加一些实用方法和模板类型,但现在这是一个简单的测试,可以了解主要思想。