c# - 奇怪的委托(delegate)引用行为

标签 c# delegates reference ienumerable stack-overflow

我需要通过其他处理函数列表(每个函数接受并返回 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;
        }
    }

}

最佳答案

getResults被捕获为变量,而不是值。我不太喜欢您在这里使用的整体方法(看起来很复杂),但是您应该能够通过更改捕获来修复 stackoverflow:

    foreach (var item in valuesToAppend)
    {
         var tmp1 = getResults;
         var tmp2 = item;
         getResults = () => ProcessValues(() => tmp1(),tmp2);
    }

附注:IEnumerable[<T>]已经有点可重复,您只需调用 foreach另一次 - 是 IEnumerator[<T>] (尽管 Reset() )不是 - 但是,我认为值得尝试这样做而不需要重复枚举,因为在一般情况下 em> 这根本不能保证有效。


这是一个更简单的(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);
        }
    }
}

关于c# - 奇怪的委托(delegate)引用行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4849359/

相关文章:

c# - 如何在 xamarin 跨平台应用程序中创建支持 sqlite 的 PCL

ios - 将 App Delegate 从 Objective-C 换成 Swift?

c - 将 union 指针声明为函数

c++ - 主流编译器是否将按引用传递的基本类型转换为按复制传递?

c++ - 右值、左值和正式定义

c# - 哪里是处理在 AddDbContext 中创建的 SqlConnection 对象的好地方? (.Net 核心 2.2)

c# - 如何在同一项目中使用 MVC Controller 和 WebAPI Controller

c# - 从 .NET 程序集透明地访问 native 内存

c# - 将委托(delegate)放在哪里。 .

Java:将内容从一个变量移动到另一个变量