我需要通过其他处理函数列表传递源函数(返回IEnumerable
)的结果(每个函数都取一个IEnumerable
)。
到目前为止,一切都很好,但我还需要允许处理函数对其输入枚举执行多个循环。
因此,我认为我不会传入IEnumerable<T>
,而是将输入参数更改为Func<IEnumerable<T>>
,并允许每个函数在需要时重新启动枚举。
不幸的是,我现在正在获得堆栈溢出,其中最终处理函数调用自身而不是将请求传回链中。
示例代码有点做作,但希望能让您了解我想要实现的目标。
class Program
{
public static void Main(string[] args)
{
Func<IEnumerable<String>> getResults = () => GetInputValues("A", 5);
List<String> valuesToAppend = new List<String>();
valuesToAppend.Add("B");
valuesToAppend.Add("C");
foreach (var item in valuesToAppend)
{
getResults = () => ProcessValues(() => getResults(),item);
}
foreach (var item in getResults())
{
Console.WriteLine(item);
}
}
public static IEnumerable<String> GetInputValues(String value, Int32 numValues)
{
for (int i = 0; i < numValues; i++)
{
yield return value;
}
}
public static IEnumerable<String> ProcessValues(Func<IEnumerable<String>> getInputValues, String appendValue)
{
foreach (var item in getInputValues())
{
yield return item + " " + appendValue;
}
}
}
答案 0 :(得分:4)
getResults
被捕获为变量,而不是值。我真的不喜欢你在这里使用的整体方法(看起来很复杂),但你应该能够通过改变捕获来修复stackoverflow:
foreach (var item in valuesToAppend)
{
var tmp1 = getResults;
var tmp2 = item;
getResults = () => ProcessValues(() => tmp1(),tmp2);
}
在旁注:IEnumerable[<T>]
已经有点可重复,您只需再次呼叫foreach
- 即IEnumerator[<T>]
即Reset()
}})不是 - 而且,我认为值得做这个没有需要重复枚举,因为在一般情况下根本不能保证工作。
这是一个更简单的(IMO)实现,具有相同的结果:
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
public static void Main() {
IEnumerable<String> getResults = Enumerable.Repeat("A", 5);
List<String> valuesToAppend = new List<String> { "B", "C" };
foreach (var item in valuesToAppend) {
string tmp = item;
getResults = getResults.Select(s => s + " " + tmp);
}
foreach (var item in getResults) {
Console.WriteLine(item);
}
}
}