提问人:Bondolin 提问时间:11/8/2023 最后编辑:VLAZBondolin 更新时间:11/9/2023 访问量:75
如何将值传递给迭代器
How to Pass Value to Iterator
问:
在 JavaScript 中,我们有运算符,它能够返回一个值,该值可以选择性地通过该方法提供给生成器。从下一个:yield
next()
参数
value
可选
要发送到生成器的值。该值将作为表达式的结果进行赋值。例如,在 中,传递给函数的值将分配给 。
yield
variable = yield expression
.next()
variable
并产生:
返回值
返回传递给生成器方法的可选值以继续其执行。
next()
在 C# 中,我理解粗略的等效项是 IEnumerator.MoveNext()。
但是,虽然采用可选参数,但 中似乎没有任何等效参数。Generator.prototype.next()
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
希望这对任何有相同问题的人有用,并很高兴听到您可能有的任何其他想法。我想我会在实际生产使用它之前清理它,也许添加一些实用方法和模板类型,但现在这是一个简单的测试,它的主要思想。
评论
IEnumerator.MoveNext()
不接受参数。您将无法更改呼叫中的顺序,如果这是您尝试执行的操作。您可以创建一个返回 .MoveNext()
IEnumerable<T>
MoveNext
next(arg)
yield
call
next(result)