5

基本的に、これはしばらくの間私の頭の中にありました...そして私はあなたの意見を読みたいです

Jon Skeet の素晴らしい本「C# in Depth, Second Edition」を読みましたが、カスタム イベントを宣言するときに次のようなものを使用することをお勧めします。

public event Action<string> MyEvent = delegate { };

この宣言により、イベントが発生する前にnullity チェック ステートメントから解放されるため、代わりに次のようにします。

    if (this.MyEvent != null)
    {
        this.MyEvent("OMG osh");
    }

簡単に呼び出すことができます:

this.MyEvent("OMG osh");

そして、私たちのコードは簡単に機能します。

このようにイベントを宣言すると、イベントは空のデリゲートで初期化されるため、null をチェックする必要はありません。

これはイベントを宣言する別の方法であり、同等です

private Action<string> myDelegate;
public event Action<string> MyEvent
{
    add
    {
        this.myDelegate += value;
    }
    remove
    {
        this.myDelegate -= value;
    }
}

詳細情報: http://csharpindepth.com/Articles/Chapter2/Events.aspx

職場で何人かのフェローと話し合ったところ、このトピックについて話し合っていました。彼らは、イベントのすべてのサブスクリプションを一度にクリアする必要がある場合があると主張していました。同じパターンを使い続けたい場合は、空のデリゲートでイベントを再初期化する必要があります。彼らはまた、マルチスレッドのシナリオで何が起こるかを尋ねていました。それが私がこの質問をした主な理由です

質問

  1. このパターンに従ってイベントを宣言するときと null をチェックするときに、(おそらくマルチスレッドを使用している場合に) 隠れた意味があるかどうかを知りたい

  2. このパターンを使用すると、いくつかのif条件が効果的に削除され、結果としてjumpステートメントが削除されます。これは、全体的なパフォーマンスの面で優れているのではないでしょうか?

乾杯

4

2 に答える 2

3

読みやすさと開発チームの期待よりも、パフォーマンスには関心がありません。使用パターンを知らない他の開発者に、「ああ、誰かがデリゲート呼び出しを適切に使用して null をチェックするのを忘れているようだ」と考えてほしくありません。

マルチスレッドのシナリオに対処するには、基礎となるデリゲートのローカル コピーを作成する必要があることを常に理解していました。これにより、サブスクライバーが呼び出されたときに、そのリストの反復中にサブスクライバーのリストが変更された場合でも、すべてのサブスクライバーに発火できます。

私はまだこの拡張メソッドを使用して定型コードを保存することについて疑問に思っていると言いました(複数の引数のオーバーロードを使用)

サブスクライバーが誰がイベントを起動したかを知る必要がない場合、私は EventHandler イベントよりも Action を好む傾向があります。

public static class ActionExtension
{
    public static void SafeInvoke<T>(this Action<T> action, T arg)
    {
        var temp = action;
        if (temp != null)
        {
            temp(arg);
        }
    }
}

public event Action<string> InterestingEvent;
// event invoker
InterestingEvent.SaveInvoke("Boo!");
于 2012-07-18T08:04:37.427 に答える