C#中的代理问题

mal*_*lay 7 c# delegates closures

在下面的程序中,DummyMethod总是打印5.但是如果我们使用注释代码,我们会得到不同的值(即1,2,3,4).任何人都可以解释为什么会这样吗?

        delegate int Methodx(object obj);

        static int DummyMethod(int i)
        {
            Console.WriteLine("In DummyMethod method i = " + i);
            return i + 10;
        }

        static void Main(string[] args)
        {    
            List<Methodx> methods = new List<Methodx>();

            for (int i = 0; i < 5; ++i)
            {
                methods.Add(delegate(object obj) { return DummyMethod(i); });
            }

            //methods.Add(delegate(object obj) { return DummyMethod(1); });
            //methods.Add(delegate(object obj) { return DummyMethod(2); });
            //methods.Add(delegate(object obj) { return DummyMethod(3); });
            //methods.Add(delegate(object obj) { return DummyMethod(4); });

            foreach (var method in methods)
            {
                int c = method(null);
                Console.WriteLine("In main method c = " + c);
            }
        }
Run Code Online (Sandbox Code Playgroud)

此外,如果使用以下代码,我会得到所需的结果.

        for (int i = 0; i < 5; ++i)
        {
            int j = i;
            methods.Add(delegate(object obj) { return DummyMethod(j); });
        } 
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 17

问题是你i在每个委托中捕获相同的变量- 在循环结束时只有值5.

相反,您希望每个委托捕获一个不同的变量,这意味着在循环中声明一个新变量:

for (int i = 0; i < 5; ++i)
{
    int localCopy = i;
    methods.Add(delegate(object obj) { return DummyMethod(localCopy); });
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常常见的"问题" - 您可以在我的闭包文章中阅读更多有关捕获的变量和闭包的内容.

  • 看看最后的链接.让你头脑发热的是,它不是被捕获的变量*值* - 它本身就是变量. (2认同)