如何告诉 lambda 函数在 C# 中捕获副本而不是引用? [英] How to tell a lambda function to capture a copy instead of a reference in C#?

查看:35
本文介绍了如何告诉 lambda 函数在 C# 中捕获副本而不是引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在学习 C#,我正在尝试理解 lambdas.在下面的示例中,它打印了 10 次 10 次.

I've been learning C#, and I'm trying to understand lambdas. In this sample below, it prints out 10 ten times.

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 变量的引用或指针,并且每次循环迭代时都会为同一个引用分配一个新值.有没有办法强制 lamda 改为获取副本,例如 C++0x 语法

Obviously, the generated class behind the lambda is storing a reference or pointer to the int i variable, and is assigning a new value to the same reference every time the loop iterates. Is there a way to force the lamda to grab a copy instead, like the C++0x syntax

[&](){ ... } // Capture by reference

对比

[=](){ ... } // Capture copies

推荐答案

编译器正在做的是将 lambda 和 lambda 捕获的任何变量拉入编译器生成的嵌套类中.

What the compiler is doing is pulling your lambda and any variables captured by the lambda into a compiler generated nested class.

编译后你的例子看起来很像这样:

After compilation your example looks a lot like this:

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 循环中进行复制,编译器会在每次迭代中生成新对象,如下所示:

By making a copy within the for loop, the compiler generates new objects in each iteration, like so:

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

这篇关于如何告诉 lambda 函数在 C# 中捕获副本而不是引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆