问题描述
Javascript 有一个 yield*
,用于委托给另一个生成器或可迭代对象,因此以下用例产生 1 2 3 4 5 6 7 8 9
:
for (const n of func1(2,5,8)) console.log(n)
function* func1(...nrs) {
for (const n of nrs) {
yield* func2(n)
}
}
function* func2(nr) {
yield nr - 1
yield nr
yield nr + 1
}
问题:是否已经或有任何计划在 C# 中提供与 yield*
等效的功能?
我想在 C# 中做等效的唯一方法需要 func1
中的两个循环,例如:
static void Main(string[] args)
{
foreach(var n in func1(2,8)) Console.WriteLine(n);
}
static IEnumerable<int> func1(params int [] nrs) {
foreach (var iter in nrs)
foreach (var n in func2(iter))
yield return n;
}
static IEnumerable<int> func2(int nr) {
yield return nr - 1;
yield return nr;
yield return nr + 1;
}
解决方法
虽然没有与 yield*
等效的方法,但您可以在示例中使用 Enumerable.SelectMany
实现相同的效果:
static IEnumerable<int> func1(params int[] nrs)
=> nrs.SelectMany(func2);
SelectMany
也有延迟执行,与 yield
一样。
不幸的是,您无法将其与另一个 yield
语句结合使用;在这种情况下,您将需要一个 foreach
:
static IEnumerable<int> func1(params int[] nrs)
{
yield return 0; // Another yield
foreach (var n in nrs.SelectMany(func2)) yield return n; // Loop now needed
}