如何告诉lambda函数捕获副本而不是C#中的引用?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (55)

正在试着理解Lambdas

class Program
{
    delegate void Action();
    static void Main(string[] args)
    {
        List<Action> actions = new List<Action>();

        for (int i = 0; i < 10; ++i )
            actions.Add(()=>Console.WriteLine(i));

        foreach (Action a in actions)
            a();
    }
}

显然,在lambda后面生成的类正在存储指向int i变量

[&](){ ... } // Capture by reference
[=](){ ... } // Capture copies
提问于
用户回答回答于

编译后的示例如下所示:

class Program
{
        delegate void Action();
        static void Main(string[] args)
        {
                List<Action> actions = new List<Action>();

                DisplayClass1 displayClass1 = new DisplayClass1();
                for (displayClass1.i = 0; displayClass1.i < 10; ++displayClass1.i )
                        actions.Add(new Action(displayClass1.Lambda));

                foreach (Action a in actions)
                        a();
        }

        class DisplayClass1
        {
                int i;
                void Lambda()
                {
                        Console.WriteLine(i);
                }
        }
}

通过在for循环中创建一个副本,编译器将在每次迭代中生成新的对象,如下所示:

for (int i = 0; i < 10; ++i)
{
    DisplayClass1 displayClass1 = new DisplayClass1();
    displayClass1.i = i;
    actions.Add(new Action(displayClass1.Lambda));
}
用户回答回答于

唯一的解决办法是在lambda内做一个本地拷贝和引用

扫码关注云+社区

领取腾讯云代金券