2012-02-06 9 views
7

何かが私のクラスでイベントをサブスクライブする、または私は方法などでサブスクリプション/ unsubsriptionをラップする必要があるときに通知されているのいずれかの方法があります:何かイベント/デリゲートを購読したときに通知を受ける方法はありますか?

public class MyClass : ISomeInterface 
{ 
    public event SomeEventHandler SomeEvent; //How do I know when something subscribes? 

    private void OnSomeEventSubscription(SomeEventHandler handler) 
    { 
      //do some work 
    } 

    private void OnSomeEventUnsubscription(SomeEventHandler handler) 
    { 
      //do some work 
    } 
} 

代わりの

public class MyClass : ISomeInterface 
{ 
    private SomeEventHandler _someEvent; 

    public void SubscribeToSomeEvent(SomeEventHandler handler) 
    { 
      _someEvent += handler; 

      //do some work 
    } 

    public void UnsubscribeFromSomeEvent(SomeEventHandler handler) 
    { 
      _someEvent -= handler; 

      //do some work 
    }  
} 

理由は、イベントは既にISomeInterfaceに直接公開されているためですが、この特定の実装では、スタッフがいつ購読/退会するかを知る必要があります。

答えて

10

あなたはあなたのイベントのためのカスタムアクセサを書くことができます。

private SomeEventHandler _someEvent; 
public event SomeEventHandler SomeEvent 
{ 
    add 
    { 
     _someEvent += value; 
     Console.WriteLine("Someone subscribed to SomeEvent"); 
    } 
    remove 
    { 
     _someEvent -= value; 
     Console.WriteLine("Someone unsubscribed from SomeEvent"); 
    } 
} 
+1

このコードでは、イベントサブスクリプションはスレッドセーフではありません。これを達成する簡単な方法は、 '_someEvent'をイベントとしてマークすることです。 – CodesInChaos

+0

華麗な、ありがとう! – GazTheDestroyer

1

トーマスはすでにこれを答えたが、イベントサブスクリプションがあるので、私はまた、あなたがセクションの追加と削除]のいずれかのクリティカルセクションをロックする必要があるかもしれないことを追加しようと思いましたスレッドセーフではありません。つまり、誰があなたに接続するのか、またいつ接続するのか分かりません。例:

private readonly object _objectLock = new object(); 
    private SomeEventHandler _someEvent; 

    public event SomeEventHandler SomeEvent 
    { 
     add 
     {  
      lock(_objectLock) 
      { 
       _someEvent += value; 
       // do critical processing here, e.g. increment count, etc could also use Interlocked class. 
      } // End if 
     } // End of class 
     remove 
     { 
      lock(_objectLock) 
      { 
       _someEvent -= value; 
       // do critical processing here, e.g. increment count, etc could also use Interlocked class. 
      } // End if 
     } // End if 
    } // End of event 
+0

'_someEvent'を含むのを忘れてしまいました。単なるフィールドの場合、コードはスレッドセーフでもありません。 – CodesInChaos

+0

はい、そうです - C#4.0では_someEventをフィールドのようなイベントとして宣言すると暗黙のロックが得られますので、 "Private Event SomeEventHandler _someEvent"の場合は、値を追加/削除するための追加/削除内のロック必須ではありません。 – Jeb

関連する問題