En una revisión de código, tropecé con este fragmento (simplificado) código para anular el registro de un controlador de eventos:Cómo anular el registro correctamente un controlador de eventos
Fire -= new MyDelegate(OnFire);
pensé que esto no anular el registro del controlador de eventos, ya que crea un nuevo delegado que nunca se había registrado antes. Pero al buscar MSDN, encontré varias muestras de código que usan este modismo.
así que empecé un experimento:
internal class Program
{
public delegate void MyDelegate(string msg);
public static event MyDelegate Fire;
private static void Main(string[] args)
{
Fire += new MyDelegate(OnFire);
Fire += new MyDelegate(OnFire);
Fire("Hello 1");
Fire -= new MyDelegate(OnFire);
Fire("Hello 2");
Fire -= new MyDelegate(OnFire);
Fire("Hello 3");
}
private static void OnFire(string msg)
{
Console.WriteLine("OnFire: {0}", msg);
}
}
Para mi sorpresa, ocurrió lo siguiente:
Fire("Hello 1");
produjo dos mensajes, como se esperaba.Fire("Hello 2");
produjo un mensaje!
Esto me convenció de que unregisteringnew
delegados funciona!Fire("Hello 3");
lanzó unNullReferenceException
.
La depuración del código mostró queFire
esnull
después de anular el registro del evento.
Sé que para los controladores de eventos y delegados, el compilador genera una gran cantidad de código detrás de la escena. Pero todavía no entiendo por qué mi razonamiento es incorrecto.
¿Qué me estoy perdiendo?
pregunta adicional: del hecho de que es Fire
null
cuando no hay eventos registrados, llego a la conclusión de que en todas partes se activa un evento, se requiere un cheque contra null
.
Sí. Para complementar: esto me confundió por un tiempo demasiado, sobre todo porque en C# que puede hacer Fire + = new MyDelegate (OnFire) o Fire + = OnFire; Este último parece ser más simple, pero es solo azúcar sintáctico para el primero. –
@Nicholas Piasecki: Gracias; Actualicé mi respuesta para notar esa taquigrafía (bastante útil). –
Puede valer la pena señalar que agregar un delegado de multidifusión y luego anular su suscripción puede generar resultados incorrectos si alguno de los métodos dentro de ese delegado de multidifusión también se suscribe y anula la suscripción individual. – supercat