¿Es posible cancelar la suscripción a un método anónimo de un evento?
Si me suscribo a un evento como este:
void MyMethod()
{
Console.WriteLine("I did it!");
}
MyEvent += MyMethod;
Puedo cancelar la suscripción de esta manera:
MyEvent -= MyMethod;
Pero si me suscribo usando un método anónimo:
MyEvent += delegate(){Console.WriteLine("I did it!");};
¿Es posible darse de baja de este método anónimo? ¿Si es así, cómo?
Respuestas:
Solo mantenga una referencia al delegado.
fuente
Una técnica es declarar una variable para contener el método anónimo que luego estaría disponible dentro del propio método anónimo. Esto funcionó para mí porque el comportamiento deseado era darse de baja después de que se manejó el evento.
Ejemplo:
fuente
De memoria, la especificación explícitamente no garantiza el comportamiento de ninguna manera cuando se trata de equivalencia de delegados creados con métodos anónimos.
Si necesita darse de baja, debe usar un método "normal" o retener al delegado en otro lugar para que pueda darse de baja con exactamente el mismo delegado que solía suscribirse.
fuente
En 3.0 se puede acortar a:
fuente
Desde que se lanzó la función de funciones locales C # 7.0 , el enfoque sugerido por J c se vuelve realmente claro.
Entonces, honestamente, aquí no tienes una función anónima como variable. Pero supongo que la motivación para usarlo en su caso se puede aplicar a las funciones locales.
fuente
En lugar de mantener una referencia a cualquier delegado, puede instrumentar su clase para devolver la lista de invocación del evento a la persona que llama. Básicamente, puede escribir algo como esto (suponiendo que MyEvent se declare dentro de MyClass):
Por lo tanto, puede acceder a toda la lista de invocación desde fuera de MyClass y cancelar la suscripción de cualquier controlador que desee. Por ejemplo:
He escrito una publicación completa sobre esta técnica aquí .
fuente
Enfoque poco convincente:
Esto puede no funcionar o ser el método más eficiente, pero debe hacer el trabajo.
fuente
Si desea controlar la cancelación de la suscripción, debe seguir la ruta indicada en su respuesta aceptada. Sin embargo, si solo le preocupa limpiar las referencias cuando su clase de suscripción queda fuera de alcance, entonces hay otra solución (ligeramente complicada) que implica el uso de referencias débiles. Acabo de publicar una pregunta y respuesta sobre este tema.
fuente
Una solución simple:
simplemente pase la variable eventhandle como parámetro a sí misma. Evento si tiene el caso de que no puede acceder a la variable creada original debido a subprocesos múltiples, puede usar esto:
fuente
MyEvent -= myEventHandlerInstance;
ejecutarse? Si es posible, tendría un error. Pero no estoy seguro si ese es el caso.si desea referirse a algún objeto con este delegado, puede usar Delegate.CreateDelegate (Type, Object target, MethodInfo methodInfo) .net considere que el delegado es igual por target y methodInfo
fuente
Si la mejor manera es mantener una referencia en eventHandler suscrito, esto se puede lograr usando un Diccionario.
En este ejemplo, tengo que usar un método anónimo para incluir el parámetro mergeColumn para un conjunto de DataGridViews.
El uso del método MergeColumn con el parámetro enable establecido en true habilita el evento mientras que el uso con false lo deshabilita.
fuente