3

この質問にはすでに答えがあります。

C#でイベントを発生させるためのさまざまなコーディングスタイルを見ました。 最初のスタイルは以下から構成されています。

- イベントハンドラ

    public delegate void NumberReachedEventHandler(object sender, 
    NumberReachedEventArgs e);

-イベント

    public event NumberReachedEventHandler NumberReached;

- イベントを発生させる方法

    protected virtual void OnNumberReached(NumberReachedEventArgs e)
    {
        if(NumberReached != null)
        {
            NumberReached(this, e);
        }
    }

2番目のスタイルは、しかし、イベントを起動するための異なる方法があります。

    protected virtual void OnNumberReached(NumberReachedEventArgs e)
    {
        NumberReachedEventHandler handler = NumberReached;
        if(handler != null)
        {
            handler(this, e);
        }
    }

私には、1つのスタイルで "event"がnullかどうかをチェックし、2番目のスタイルでデリゲートがnullかどうかをチェックしているようです。しかし、私の理解するところでは、イベントは単にデリゲートのインスタンスにすぎないため、どちらの方法でコードを記述しても利点があるかどうかと思います。もしそうなら、説明してください。前もって感謝します。

2 답변


11

どちらも、イベントに関連付けられているデリゲートがnullかどうかを確認しています。

ローカルへの保存の目的は、私はあなたを愛していますスレッドコードでのスタイルの競合。

ローカルを使用することは2つの潜在的なレースのうちの1つを排除するだけであることに注意することは重要です。詳細については、このテーマに関する私の2009年の記事を参照してください。http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx

そしてまたこの質問:

C#のイベントとスレッドの安全性


0

私が理解していることからこの答えは、1つ目はスレッドセーフではないのに対し、2つ目はスレッドセーフです。

protected virtual void OnNumberReached(NumberReachedEventArgs e)
{
    //If number reached is changed from after this check
    if(NumberReached != null)
    {
        //and between this call, it could still result in a
        //NullReferenceException
        NumberReached(this, e);
    }
}


  • これが2つの可能性のある競合状態のうちの1つを排除することに注意することは重要です。これはnullを間接参照しませんが、それでもイベントハンドラを呼び出すことができます。後にそれは購読していない、それはレースです。 - Eric Lippert

リンクされた質問


関連する質問

最近の質問