2010-01-27

Resharper:”Access to modified closure”

using System;

namespace ConsoleApplication1
{
    class Program
    {
        delegate void MyDelegate();
        static void Main()
        {
            MyDelegate d = null;
            string s;
            for (var i = 0; i < 10; i++)
            {
               s = i.ToString();
                d += () => Console.WriteLine(s);
            }
            d();
        }
    }
}

输出是什么?如果把s的定义放到循环内部呢?

using System;

namespace ConsoleApplication1
{
    class Program
    {
        delegate void MyDelegate();
        static void Main()
        {
            MyDelegate d = null;
            //string s;
            for (var i = 0; i <= 10; i++)
            {
                string s;
                s = i.ToString
();
                d += () => Console.WriteLine(s);
            }
            d();
        }
    }
}

 

第一种情况下,由于s是在循环外部定义的,所有的delegate都是共享的,所以,每循环一次,s增1,到最后,s变为10,最后执行d()的时候,用的都是同一个s,因此输出都是10。resharper 会提定义局部变量保存s的拷贝,如下,这样,每一次执行都会使用自己的copy,也就会输出0 1 2 3 ….10

using System;

namespace ConsoleApplication1
{
    class Program
    {
        delegate void MyDelegate();
        static void Main()
        {
            MyDelegate d = null;
            string s;
            for (var i = 0; i <= 10; i++)
            {
               s = i.ToString();
                string s1 = s;
                d += () => Console.WriteLine(s1);
            }
            d();
        }
    }
}

 

C#: Anonymous methods are not closures

The implementation of anonymous methods in C# and its consequences (part 1)

No comments: