5

C# では、同じイベントのディスパッチの途中で、イベントのメソッドを登録したくなることがあります。たとえば、同じイベントの連続するディスパッチに基づいて状態を遷移させるクラスがある場合、最初の状態のハンドラーを登録解除し、2 番目のハンドラーを登録することができます。ただし、次にイベントが発生するまで、2 番目のハンドラーをディスパッチしたくありません。

良いニュースは、C# の Microsoft 実装がまさにこのように動作するように見えることです。イベント登録構文の砂糖は、System.Delegate.Combine への呼び出しに置き換えられます。これは、現在の呼び出しリストと新しいメソッドを別のリストに連結し、それをイベント プロパティに割り当てるだけです。これにより、まさに私が望む動作が得られます。

だから、私の質問は: これは言語標準によって保証された動作ですか? 私は自分の C# コードを他のプラットフォームで mono の下で実行できるようにしたいと考えており、一般的に、その実装に基づいて言語標準について推測していないことを確認したいと考えています。

MSDN で決定的な情報を見つけることができませんでした。

私が話していることの具体的な例が必要な場合は、ここに例を示します。

    delegate void TestDelegate();
    static event TestDelegate TestEvent;

    static void Main (string[] args) {
        TestEvent += TestDelegateInstanceFirst;
        TestEvent();
        TestEvent();
    }

    static void TestDelegateInstanceFirst () {
        Console.WriteLine("First");
        TestEvent += TestDelegateInstanceSecond;
    }

    static void TestDelegateInstanceSecond () {
        Console.WriteLine("Second");
    }

少なくとも Windows では、出力は次のようになります。

First
First
Second
4

1 に答える 1

9

はい、保証されています。

統合された C# 3.0 仕様のセクション 15.1 から:

ただし、null 以外の 2 つのデリゲート インスタンスが結合されると、それらの呼び出しリストが (左オペランド、次に右オペランドの順序で) 連結され、2 つ以上のエントリを含む新しい呼び出しリストが形成されます。

「新しい呼び出しリスト」に注意してください。そして再びセクション15.3で:

インスタンス化されると、デリゲート インスタンスは常に同じターゲット オブジェクトとメソッドを参照します。2 つのデリゲートが結合されるか、1 つが別のデリゲートから削除されると、新しいデリゲートが独自の呼び出しリストを持つことを思い出してください。結合または削除されたデリゲートの呼び出しリストは変更されません。

最後に、System.Delegate の MSDN には次のように記載されています。

デリゲートは不変です。作成されたデリゲートの呼び出しリストは変更されません。

CLI 仕様に何かあると思われます - ご希望があれば確認しますが、これら 3 つが十分な自信を与えてくれることを願っています :)

于 2008-09-26T19:36:29.620 に答える