ディスパッチ中にc#でイベントに登録した場合、そのディスパッチ中に再度呼び出されないことが保証されていますか?
質問
C#では、同じイベントのディスパッチの途中でイベントのメソッドを登録したい場合があります。たとえば、同じイベントの連続するディスパッチに基づいて状態を遷移するクラスがある場合、最初の状態のハンドラー自体の登録を解除し、2番目のハンドラーを登録することができます。ただし、次にイベントが発生するまで、2番目のハンドラーをディスパッチしたくありません。
良いニュースは、MicrosoftのC#の実装がこのように動作するように見えることです。イベント登録構文のシュガーは、System.Delegate.Combineの呼び出しに置き換えられます。これは、現在の呼び出しリストと新しいメソッドを個別のリストに連結して、イベントプロパティに割り当てるだけです。これにより、必要な動作が正確に得られます。
それで、私の質問は次のとおりです。これは言語標準で保証された動作ですか?私はモノの下で他のプラットフォームでC#コードを実行できるようにしたいので、一般的に、その実装に基づいて言語標準についての仮定を立てないようにしたいと考えています。
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
解決
はい、保証されています。
統一されたC#3.0仕様のセクション15.1から
ただし、2つの非nullデリゲート インスタンスが結合され、その 呼び出しリストは連結されています 順序左オペランド、次に右 オペランド—新しい呼び出しリストを作成するには、 2つ以上のエントリが含まれています。
「新しい呼び出しリスト」に注意してください。そして再びセクション15.3で:
インスタンス化されると、インスタンスを委任します 常に同じターゲットオブジェクトを参照する および方法。覚えておいて、2 デリゲートが結合されるか、1つが 別の新しいデリゲートから削除されました 独自の呼び出しリストによる結果。 デリゲートの呼び出しリスト 結合または削除は変更されません。
最後に、MSDN for System.Delegateの状態:
デリゲートは不変です。作成したら、 デリゲートの呼び出しリストは 変わらない。
CLI仕様に何かあるのではないかと思います-希望するかどうか確認しますが、これら3つが十分な自信を与えてくれることを願っています:)