何かイベント/デリゲートを購読したときに通知を受ける方法はありますか?

何かがクラスのイベントに登録したときに通知を受ける方法はありますか?またはメソッドのサブスクリプション/サブスクリプションをラップする必要がありますか?

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 に直接公開されているからです。しかし、この特定の実装では、いつstuffが購読/購読解除を行うかを知る必要があります。

7

2 答え

イベント用のカスタムアクセサを記述することができます:

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");
    }
}
10
追加された
ブリリアント、ありがとう!
追加された 著者 GazTheDestroyer,
このコードでは、サブスクリプションはスレッドセーフではありません。これを達成する簡単な方法は、イベントとして _someEvent をマークすることです。
追加された 著者 CodesInChaos,

Thomasはすでにこれに答えていますが、イベントのサブスクリプションは決してスレッドセーフではないため、誰があなたにいつ接続するか分からないため、追加のセクションを削除する必要があるかもしれないと付け加えました。例えば。:

    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
1
追加された
_someEvent を含めるのを忘れました。単なるフィールドの場合、コードはスレッドセーフでもありません。
追加された 著者 CodesInChaos,
はい、あなたは正しいですか?C#4.0では_someEventをフィールドのようなイベントとして宣言すると暗黙のロックが得られますので、 "Private Event SomeEventHandler _someEvent"の場合は、値を追加/削除するための追加/削除内のロックは必須ではありません。
追加された 著者 Jeb,