2012-01-10 16 views
14

estoy usando ReSharper 5.1 análisis de código muchas veces me sale un comentario de ReSharper comoanulación de la suscripción de eventos a través de delegado anónimo

"darse de baja de eventos a través de delegado anónimo"

#Part of Code 

if (((bool)e.NewValue)) 
{ 
    listView.PreviewTextInput += (o,args) => 
     listView_PreviewTextInput(o,args,listView); 
} 
else 
{ 
    listView.PreviewTextInput -= (o, args) => 
     listView_PreviewTextInput(o, args, listView); 
} 

¿Cómo podría corregir o optimze esta cosa

Respuesta

29

puede extraer el Lamdba a una variable:

EventHandler func = (sender, e) => 
    listView_PreviewTextInput(sender, e, listView); 

if (((bool)e.NewValue)) 
{ 
    listView.PreviewTextInput += func; 
} 
else 
{ 
    listView.PreviewTextInput -= func; 
} 
+0

Gracias pero el 'EventHandler' debe ser específico ¿no? Porque me da un error ... 'System.EvenTArgs no es asignable a TextCompositonEventArgs' – Ankesh

+0

En ese caso' listView.PreviewTextInput' no es 'EventHandler' sino probablemente' EventHandler ', pero no hay forma de que que lo sepa, ya que no lo demostraste en tu pregunta. – Steven

+0

Sip ... mi mal .. Gracias de todas formas ... :) – Ankesh

6

¡Advertencia! Accepted answer de Steven es incorrecto, todo lo que hace es enmascarar un problema que resharper está advirtiendo.

Cada vez código dado se ejecuta

EventHandler func = (sender, e) => 
    listView_PreviewTextInput(sender, e, listView); 

obtendrá un fresco (ya que puede capturar diferentes listView) instancia del delegado anónimo guardado en func, una instancia que no está suscrito a ningún evento todavía, por lo a su vez, este código

listView.PreviewTextInput -= func; 

no hará nada, ya que no puede darse de baja de un evento al que no está suscrito. Esto dará lugar a errores alucinantes como controladores de eventos 'llama dos veces', pérdidas de memoria, etc.

En realidad, Jon Skeet dice que may work in some cases:

El C# especificación establece de manera explícita (IIRC) que si tiene dos funciones anónimas (métodos anónimos o expresiones lambda) es puede o no puede crear delegados iguales de ese código.

por ejemplo cuando el compilador no genera una nueva instancia cada vez, verá un buen comportamiento.

Pero eso no es confiable y ciertamente no funcionaría en el caso descrito en la pregunta inicial con la variable capturada listView.

Así que mi sugerencia es:

Use funciones anónimas como controladores de eventos SOLAMENTE si nunca tendrán que darse de baja.

Cuestiones relacionadas