Cuando se utilizan problemas de myDelegate -= eventHandler
ReSharper (versión 6):
La resta del delegado tiene un resultado impredecible
El racional detrás de esto se explica por JetBrains aquí . La explicación tiene sentido y, después de leerla, dudo de todos mis usos de -
los delegados.
¿Cómo, pues ,
- ¿Puedo escribir un evento no automático sin hacer que ReSharper esté malhumorado?
- o, ¿hay una manera mejor y / o "correcta" de implementar esto?
- o, ¿puedo ignorar ReSharper?
Aquí está el código simplificado:
public delegate void MyHandler (object sender);
MyHandler _myEvent;
public event MyHandler MyEvent
{
add
{
_myEvent += value;
DoSomethingElse();
}
remove
{
_myEvent -= value; // <-- ReSharper warning here
}
}
Respuestas:
¡No tengas miedo! La primera parte de la advertencia de ReSharper solo se aplica a la eliminación de listas de delegados. En su código, siempre está eliminando un solo delegado. La segunda parte habla sobre el pedido de delegados después de que se eliminó un delegado duplicado. Un evento no garantiza un orden de ejecución para sus suscriptores, por lo que tampoco te afecta.
ReSharper está emitiendo esta advertencia porque la sustracción de delegado de multidifusión puede tener problemas, no está condenando por completo esa característica del lenguaje. Afortunadamente, esas trampas están en casos marginales y es poco probable que las encuentres si solo estás instrumentando eventos simples. No hay manera mejor para poner en práctica sus propias
add
/remove
manipuladores, solo tienes que tomar nota.Sugeriría degradar el nivel de advertencia de ReSharper para ese mensaje a "Sugerencia" para que no se vuelva insensible a sus advertencias, que generalmente son útiles.
fuente
Delegate
No se sobrecarga+
y-
.)PIT OF SUCCESS IS THAT WAY --->
.Delegate.Combine
que "aplana" a los delegados de multidifusión, por lo que si se les da delegados [X, Y] y Z, no puede decir si el resultado debería ser [X, Y, Z] o [[ X, Y], Z] (el último delegado mantiene al[X,Y]
delegado como suTarget
, y elInvoke
método de ese delegado como suMethod
).No debe utilizar directamente delegados para sumar o restar. En cambio tu campo
En su lugar, también debe declararse como un evento. Esto resolverá el problema sin arriesgar su solución y aún tendrá el beneficio del uso de eventos.
El uso de la suma o resta del delegado es peligroso porque puede perder eventos al simplemente asignar el delegado (según la declaración, el desarrollador no inferirá directamente que se trata de un delegado de multidifusión como cuando se declara como un evento). Solo para ejemplificar, si la propiedad mencionada en esta pregunta no se marcó como un evento, el código a continuación hará que las dos primeras asignaciones se PERDERAN, porque alguien simplemente lo asignó al delegado (¡lo cual también es válido!).
Al asignar el Método 3, perdí por completo las dos suscripciones iniciales. El uso de eventos evitará este problema y al mismo tiempo eliminará la advertencia de ReSharper.
fuente
configúrelo como = nulo en lugar de usar - =
fuente
remove
método de un evento no debe eliminar todos los controladores, sino el controlador que se solicitó eliminar.