W przypadku myDelegate -= eventHandler
problemów z ReSharper (wersja 6):
Odejmowanie delegatów ma nieprzewidywalny wynik
Racjonalne uzasadnienie tego jest wyjaśnione przez JetBrains tutaj . Wyjaśnienie ma sens, a po jego przeczytaniu wątpię w to, co robię -
na delegatach.
Jak wtedy ,
- czy mogę napisać wydarzenie inne niż automatyczne bez zrzędliwości ReSharper?
- czy też jest lepszy i / lub „poprawny” sposób realizacji tego?
- czy mogę po prostu zignorować ReSharper?
Oto uproszczony kod:
public delegate void MyHandler (object sender);
MyHandler _myEvent;
public event MyHandler MyEvent
{
add
{
_myEvent += value;
DoSomethingElse();
}
remove
{
_myEvent -= value; // <-- ReSharper warning here
}
}
Odpowiedzi:
Nie bój się! Pierwsza część ostrzeżenia ReSharper dotyczy tylko usuwania list delegatów. W swoim kodzie zawsze usuwasz jednego delegata. W drugiej części omówiono porządkowanie delegatów po usunięciu zduplikowanego delegata. Wydarzenie nie gwarantuje kolejności realizacji swoim subskrybentom, więc tak naprawdę nie wpływa na Ciebie.
ReSharper wydaje to ostrzeżenie, ponieważ odejmowanie delegatów multiemisji może mieć problemy, nie potępia całkowicie tej funkcji języka. Na szczęście te pułapki występują w marginalnych przypadkach i jest mało prawdopodobne, abyś je spotkał, jeśli tylko instrumentujesz proste zdarzenia. Nie ma lepszego sposobu na implementację własnych
add
/remove
handlerów, po prostu musisz zwrócić uwagę.Proponuję obniżyć poziom ostrzeżenia ReSharper dla tej wiadomości do „Podpowiedź”, aby nie znieczulić ich ostrzeżeń, które są zwykle przydatne.
źródło
Delegate
czy nie przeciążać+
i-
.)PIT OF SUCCESS IS THAT WAY --->
.Delegate.Combine
który „spłaszcza” delegatów multiemisji, więc jeśli ma przydzielonych delegatów [X, Y] i Z, nie może stwierdzić, czy wynikiem powinno być [X, Y, Z] czy [[ X, Y], Z] (ten ostatni delegat trzyma[X,Y]
delegata jako swojegoTarget
iInvoke
metodę tego delegata jako swojąMethod
).Nie należy bezpośrednio używać delegatów do sumowania lub odejmowania. Zamiast twojego pola
Zamiast tego powinno być również zadeklarowane jako wydarzenie. To rozwiąże problem bez ryzykowania rozwiązania i nadal będzie korzystać z funkcji zdarzenia.
Użycie sumy lub odejmowania delegata jest niebezpieczne, ponieważ możesz utracić zdarzenia podczas prostego przypisywania delegata (zgodnie z deklaracją deweloper nie wywnioskuje bezpośrednio, że jest to delegat multiemisji, gdy jest zadeklarowany jako zdarzenie). Dla przykładu, jeśli właściwość wymieniona w tym pytaniu nie została oflagowana jako zdarzenie, poniższy kod spowoduje, że dwa pierwsze przypisania zostaną UTRACONE, ponieważ ktoś po prostu przypisany do delegata (co również jest ważne!).
Podczas przypisywania Method3 całkowicie straciłem dwie początkowe subskrypcje. Użycie zdarzenia pozwoli uniknąć tego problemu i jednocześnie usunie ostrzeżenie ReSharper.
źródło
ustaw go na = null zamiast używać - =
źródło
remove
metoda zdarzenie nie powinno usunąć wszystkie programy obsługi, ale raczej handler że została wezwana do usunięcia.