2010-06-03 14 views
9

Me acabo de dar cuenta de que no entiendo completamente por qué en .NET asigna eventos usando un símbolo + =.Cómo se asignan los eventos en .NET

Me di cuenta de esto ayer cuando necesitaba para eliminar un evento y sin pensar que estaba haciendo

someobject.onsomeevent += null 

pensar que basta con retirar el evento había asignado previamente.

Después de algunas investigaciones, he descubierto que tenía que

someobject.onsomeevent -= someeventmethod; 

Después de calcular esto, me di cuenta de que no entiendo cómo se asignan los métodos de evento en .NET.

así que tengo un par de preguntas:

En primer lugar, ¿significa que puedo hacer

someobject.onsomeevent += someeventmethod; 
someobject.onsomeevent += someeventothermethod; 

Si es así, cuando onsomeevent ocurre esto que tanto conseguir golpe, y en el orden especificado o al mismo tiempo?

Además, ¿cómo puedo determinar qué métodos de eventos ya están asignados a someobject.onsomeevent?

En segundo lugar, ¿hay alguna manera de guardar los métodos de eventos en alguna clase, eliminarlos de algún objeto y ponerlos de nuevo después de que se hayan completado algunos otros procedimientos que normalmente desencadenarían el evento?

+1

Por confusión, usted debe tratar el largo (.NET 1.x) form: 'someobject.onsomeevent - = new Eventhandler (someeventmethod);' –

+0

¡Tantas buenas respuestas! ¡Gracias a todos! – Matt

Respuesta

3

Primera pregunta: Sí, puede hacerlo, siempre que las firmas de método sean compatibles con el tipo de delegado del evento.

Segunda pregunta: Sí, puedes hacerlo también. Use EventTest.GetInvocationList() para obtener los métodos registrados para su evento. Y luego use -= y += para eliminar y volver a agregar los delegados, respectivamente. Véase el siguiente ejemplo:

public class Test 
    { 
     public event EventHandler EventTest = delegate { }; 
     public void Method() 
     { 
      //get registered event handlers 
      Delegate[] invocationList = EventTest.GetInvocationList(); 

      //remove them 
      foreach (Delegate d in invocationList) 
      { 
       EventTest -= (EventHandler)d; 
      } 

      //this method won't trigger anything, because 
      //invocation list is empty 
      Method2(); 

      //re-add event handlers 
      foreach (Delegate d in invocationList) 
      { 
       EventTest += (EventHandler)d; 
      } 
     } 

     public void Method2() 
     { 
      if(EvenTest != null) 
      EventTest(this, EventArgs.Empty); 
     } 
    } 

Quité el Main() -method trivial para hacer el código más legible.

4

En relación con su primera pregunta: Obtiene el comportamiento de multidifusión por defecto. Es decir, si tiene múltiples manejadores, de manera predeterminada, los manejadores de eventos serán llamados en secuencia (a menos que uno de ellos genere una excepción). Tenga en cuenta que puede cambiar add (+=) y remove (-=) para hacer algo diferente al comportamiento predeterminado.

Jon Skeet tiene una página que explica delegates and events in C# que es posible que desee leer.

2

Entonces la respuesta es sí, sí y secuencialmente en el orden agregado.

Un evento es una instancia de la clase MulticastDelegate. Para averiguar qué delegados se asignan al evento, llame al método GetInvocationList en el evento. Ver http://msdn.microsoft.com/en-us/library/system.multicastdelegate.getinvocationlist%28v=VS.71%29.aspx

Esto le dará una variedad de delegados.Por lo tanto, podría llamar a GetInvocationList para obtener los controladores de eventos existentes; luego borre los manejadores de eventos del evento; realizar alguna acción; y luego reasignar a los controladores al evento.

2

Los delegados son 'multicast' en .NET y los eventos son envoltorios similares a propiedades. Usted puede obtener una mejor undestanding examinado en un evento en formato largo notación:

private EventHandler _handler; 

public event EventHandler MyEvent 
{ 
    add { _handler = (EventHandler)Delegate.Combine(_handler, value); } 
    remove { _handler = (EventHandler)Delegate.Remove(_handler, value); } 
} 

que normalmente se escribe todo lo anterior en 1 línea:

public event EventHandler MyEvent; 

Y para ser completa, un evento Constains an Invocationlist que procesa secuencialmente cuando se desencadena. No hay garantías sobre el orden.

2

Y sólo para cubrir un bit que no creo que nadie trataron con explicitamente, los eventos no todo el fuego, al mismo tiempo - que el fuego en la secuencia ...

Cuestiones relacionadas