5

仮定する

public class Program
{
    public static void Main(string[] args)
    {
        Program p = new Program();
        A a = new A();
        p.Do(a);
        System.Threading.Thread.Sleep(1000);
        a.Fire();
    }

    public void Do(A a)
    {
        int i = 5;
        a.ChangeViewEvent += () =>
        {
            Console.WriteLine(i);
        };
    }
}

public class A
{
    public delegate void ChangeView();
    public event ChangeView ChangeViewEvent;

    public void Fire()
    {
        if(ChangeViewEvent != null)
            ChangeViewEvent();
    }
}

が起動されたときにChangeViewEvent、イベント ハンドラーがまだ variable にアクセスできるのはiなぜですか? 範囲外にすべきではないということですか?

4

2 に答える 2

6

ChangeViewEvent が発生したときに、イベント ハンドラーがまだ変数 i にアクセスできるのはなぜですか? 範囲外にすべきではないということですか?

いいえ、ラムダ式によってキャプチャされます。コンパイラによって生成されたクラスに「リフト」されるため、「範囲外」であってもラムダ式にアクセスできます。(「スコープ外」とは、単に「単純な名前ではアクセスできない」ことを意味することに注意してください。その変数に関連付けられたストレージ スペースがなくなり、他のユーザーがアクセスできないという意味ではありません。)

ところで、これは、「値型がスタック上に存在する」というよく繰り返される虚偽が誤りである理由の1 つです。この場合、実際にはコンパイラによって生成されたクラスに巻き上げられ、最終的にヒープ上に存在する値型があります。

このトピックの詳細については、MSDNを参照してください。

于 2012-04-05T16:56:52.890 に答える
4

これをキャプチャ変数と呼びます。

http://en.wikipedia.org/wiki/Closure_%28computer_science%29#Delegates_.28C.23.2C_D.29

http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/what-are-closures.aspx

于 2012-04-05T16:56:55.250 に答える