10

私はC#に慣れていないので、この問題を思いつきました。質問: なぜ func2 が呼び出されるのですか? ああ、そしてもう1つ。デリゲートに関数を追加するとします。この関数では、別のデリゲートを呼び出しますが、最初のデリゲートに追加された他のすべての関数が、この関数がこのデリゲートを呼び出す前に呼び出されるようにしたいのですが、クリーンな解決策はありますか (getInvocationList にはあまり関心がありません)。みんなありがとう、あなたは最高です。

class Program
{
    delegate void voidEvent();
    voidEvent test;

    private void func1()
    {
        Console.Write("func1");
        test -= func2;
    }

    private void func2()
    {
        Console.WriteLine("func2");
    }

    static void Main(string[] args)
    {
        Program p = new Program();
        p.test += p.func1;
        p.test += p.func2;
        p.test();
    }
}
4

2 に答える 2

20

デリゲート (+= または -=) を変更するたびに、呼び出しリスト (呼び出されるメソッド) の完全なコピーを効果的に作成しています。

そのため、 を呼び出すと、その時点でp.test();呼び出しリスト内のすべてのデリゲートを呼び出すことになります。これらのハンドラーのいずれかの内部でこれを変更すると、次の呼び出しで変更されますが、現在実行中の呼び出しは変更されません。

于 2012-04-05T23:18:52.567 に答える
7

リードはもちろん正しい。ここで、別の方法を考えてみましょう。

class Number
{
    public static Number test;
    private int x;
    public Number(int x) { this.x = x; }
    public Number AddOne() 
    {
        return new Number(x + 1);
    }
    public void DoIt()
    {
        Console.WriteLine(x);
        test = test.AddOne();
        Console.WriteLine(x);
    }
    public static void Main()
    {
        test = new Number(1);
        test.DoIt(); 
    }
}

それは1、1、または1、2を出力する必要がありますか?なんで?

1, 1 と表示されるはずです。

test.DoIt();

それは意味しない

        Console.WriteLine(test.x);
        test = test.AddOne();
        Console.WriteLine(test.x);

! むしろ、つまり

Number temporary = test;
Console.WriteLine(temporary.x);
test = test.AddOne();
Console.WriteLine(temporary.x);

の値を変更しても、DoIttest の の値は変更されませんthis

あなたはまったく同じことをしています。の値を変更しtestても、呼び出す関数のリストは変更されません。関数の特定のリストを呼び出すように要求し、そのリストが呼び出されますthisメソッド呼び出しの途中で意味を変更するのと同じように、途中で変更することはできません。

于 2012-04-06T06:37:03.583 に答える