2012-02-06 8 views
7

non v'è alcun modo di essere avvisato quando qualcosa sottoscrive un evento nella mia classe, o ho bisogno di avvolgere di sottoscrizione/unsubsription in metodi per esempio:Un modo per essere avvisati quando qualcosa si iscrive ad un evento/delegato?

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 
    } 
} 

invece di

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 
    }  
} 

La ragione Chiedo è perché l'evento è già esposto direttamente su un ISomeInterface ma questa particolare implementazione deve sapere quando le cose si abbonano/si annullano.

risposta

10

È possibile scrivere funzioni di accesso personalizzati per il vostro evento:

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

Si noti che con questo codice di sottoscrizione evento non è protetto da thread. Un modo semplice per ottenerlo è contrassegnare '_someEvent' anche come evento. – CodesInChaos

+0

Brillante, grazie! – GazTheDestroyer

1

Thomas ha risposto a questa già ma ho pensato anche aggiungere che potrebbe essere necessario per bloccare qualsiasi sezione critica nella Aggiungere Rimuovere sezioni poiché sottoscrizione di eventi è non infilarti mai in sicurezza, ovvero non hai idea di chi si connetterà a te o quando. Es .:

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

Hai dimenticato di includere '_someEvent'. Se è solo un campo, anche il tuo codice non è sicuro. – CodesInChaos

+0

Sì hai ragione - C# 4.0 ti offre un blocco implicito se dichiari _someEvent come un evento di tipo field, quindi se è "evento privato SomeEventHandler _someEvent", quindi il blocco all'interno di aggiungi/rimuovi per aggiungere/rimuovere il valore non è richiesto. – Jeb

Problemi correlati