1

私がデリゲートの概念を理解している限り、デリゲートは単にメソッドを指しています。その後、運が良ければ、デリゲートが指しているメソッドを呼び出すことができますよね?

次のコードが与えられます。

class Program
{
    static void Main(string[] args)
    {
        Func<MyClass> myAct = GetAct();

        Method(myAct);
    }

    private static Func<MyClass> GetAct()
    {
        MyClass obj = new MyClass()
        {
            Prop1 = 5
        };

        Func<MyClass> myAct = new Func<MyClass>(
            () =>
            {
                MyClass obj2 = new MyClass();
                MyClass2 obj3 = new MyClass2()
                {
                    Prop3 = 25,
                    Prop4 = "test"
                };

                obj2.Prop2 = ((obj.Prop1 + 5) * obj3.Prop3)
                    .ToString() + obj3.Prop4;

                return obj2;
            });
        return myAct;
    }

    static void Method(Delegate func)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();

        var result = func.DynamicInvoke();
    }
}

class MyClass
{
    public int Prop1 { get; set; }
    public string Prop2 { get; set; }
}

class MyClass2
{
    public int Prop3 { get; set; }
    public string Prop4 { get; set; }
}

ここで、私のデリゲートmyAct(この場合は a Func<MyClass>) は、変数の単純な割り当てを実行する無名関数を指しています。これまでのところ特別なことは何もありません。

デリゲートを呼び出します。

私たちが期待したように、すべてがうまくいきました。しかし、問題はなぜですか?デリゲートが単に匿名メソッドを指しており、かつガベージ コレクションが実行されている場合、CLR はどのようobjにしてその値が何であるかを知ることができるでしょうか? obj関数が呼び出されたときに使用できるように、格納されている参照はどこにありますか? デリゲートの内部?

4

1 に答える 1

4

匿名メソッドは のスコープ内で定義されているGetAct()ため、CLR はスコープ変数を匿名メソッドで使用できるようにします。

これは、メンバー メソッドでインスタンス変数を使用する方法に似ています。

また、クロージャを使用する際の落とし穴を確認してください: http://msmvps.com/blogs/peterrichie/archive/2010/11/03/deep-dive-on-closure-pitfals.aspx

于 2012-05-22T18:35:54.010 に答える