2012-02-06 12 views
7

¿Hay alguna forma de ser notificado cuando algo se suscribe a un evento en mi clase, o necesito para envolver suscripción/unsubsription en los métodos por ejemplo:¿Alguna forma de ser notificado cuando algo se suscribe a un evento/delegado?

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

en lugar de

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 razón Lo pregunto es porque el evento ya está expuesto directamente en un ISomeInterface, pero esta implementación particular necesita saber cuándo se suscribe/anula la suscripción.

Respuesta

10

Puede escribir descriptores de acceso personalizados para su 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

Tenga en cuenta que con este código la suscripción de eventos no es segura. Una manera fácil de lograr eso es marcar '_someEvent' como evento también. – CodesInChaos

+0

Brillante, gracias! – GazTheDestroyer

1

Thomas ha respondido a esta ya, pero pensado También me gustaría añadir que pueda necesitar para bloquear cualquier sección crítica en el complemento quitar secciones desde la suscripción evento es nunca te preocupes, es decir, no tienes idea de quién se va a conectar contigo o cuándo. Por ejemplo:

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

Olvidó incluir '_someEvent'. Si solo se trata de un campo, tampoco tu código es seguro para subprocesos. – CodesInChaos

+0

Sí, tiene razón: C# 4.0 le otorga un bloqueo implícito si declara _someEvent como un evento parecido a un campo, por lo que si era "evento privado SomeEventHandler _someEvent", entonces el bloqueo dentro de add/remove para agregar/eliminar el valor no es requerido. – Jeb

Cuestiones relacionadas