6

これは私の他の質問で言及されており、記録に追加すると役立つかもしれないと思いました. 次のプログラムで、ローカルに定義されたデリゲートのうち、毎回最初から作成されるのではなく、Work メソッドの呼び出し間でキャッシュされるのはどれですか?

namespace Example
{
    class Dummy
    {
        public int age;
    }

    class Program
    {
        private int field = 10;

        static void Main(string[] args)
        {
            var p = new Program();

            while (true)
            {
                p.Work();
            }
        }

        void Work()
        {
            int local = 20;

            Action a1 = () => Console.WriteLine(field);
            Action a2 = () => Console.WriteLine(local);
            Action a3 = () => Console.WriteLine(this.ToString());
            Action a4 = () => Console.WriteLine(default(int));
            Func<Dummy, Dummy, bool> dummyAgeMatch = (l, r) => l.age == r.age;

            a1.Invoke();
            a2.Invoke();
            a3.Invoke();
            a4.Invoke();
            dummyAgeMatch.Invoke(new Dummy() { age = 1 }, new Dummy(){ age = 2 });
        }
    }
}
4

2 に答える 2

7

Reflector が示す内容に基づいて、最後の 2 つ (a4およびdummyAgeMatch) は MS C#3.0 コンパイラによってキャッシュされます (私の特定のビルドでは "CS$<>9_CachedAnonymousMethodDelegate5" および "CS$<>9_CachedAnonymousMethodDelegate6" と呼ばれるフィールド)。

これらはキャッシュできますが、他のものはキャプチャされた変数に依存することは明らかです。

この動作が仕様で義務付けられているとは思いませんが、Mono コンパイラはほぼ同じように動作します (変数名が異なります)。

于 2009-01-15T12:08:45.900 に答える
5

具体的な質問に答えると、最後の 2 つは何もキャプチャしないため、キャッシュされる唯一のものです。これはリフレクターで見ることができます (しかし、きれいではありません)。もちろん、args を渡すことで再利用できるように微調整できます。

Action<Program> a1 = p => Console.WriteLine(p.field);
Action<int> a2 = i => Console.WriteLine(i);
Action<Program> a3 = p => Console.WriteLine(p.ToString());
Action a4 = () => Console.WriteLine(default(int));
Func<Dummy, Dummy, bool> dummyAgeMatch = (l, r) => l.age == r.age;

そして、 / 、およびthisに渡します。それらのどれももはや何も直接キャプチャしないため、それらはすべてキャッシュできます(少なくとも私にとっては)。もちろん、(以前にキャプチャされた) 変数を直接再割り当てする機能は失われますが、FP 支持者はとにかくそれを好まないでしょう;-p 常に更新された値を戻り値として返すか、デリゲート型を宣言することができます引数付き(ただし、お勧めしません)。a1a3locala2CS$<>9__CachedAnonymousMethodDelegate5CS$<>9__CachedAnonymousMethodDelegate9ref

于 2009-01-15T12:11:26.397 に答える