W przeglądzie kodu, natknąłem się na tym (uproszczony) fragment kodu wyrejestrowania obsługi zdarzeń:Jak poprawnie wyrejestrować obsługi zdarzeń
Fire -= new MyDelegate(OnFire);
myślałem, że to nie wyrejestrować obsługi zdarzeń, ponieważ tworzy nowego delegata, który nigdy wcześniej nie był zarejestrowany. Ale szukając MSDN znalazłem kilka próbek kodu, które używają tego idiomu.
Więc zacząłem eksperyment:
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);
}
}
Ku mojemu zaskoczeniu, dodaje się:
Fire("Hello 1");
produkowane dwie wiadomości, jak oczekiwano.Fire("Hello 2");
wyprodukował jedną wiadomość!
To przekonało mnie, że wyrejestrowanie delegatównew
działa!Fire("Hello 3");
rzuciłNullReferenceException
.
Debugowanie kodu pokazało, żeFire
jestnull
po wyrejestrowaniu zdarzenia.
Wiem, że dla programów obsługi zdarzeń i delegatów kompilator generuje dużo kodu za sceną. Ale nadal nie rozumiem, dlaczego moje rozumowanie jest złe.
Czego mi brakuje?
dodatkowe pytanie: z faktu, że Fire
jest null
gdy są zarejestrowane żadne zdarzenia, dochodzę do wniosku, że wszędzie zdarzenie jest zwolniony, konieczne jest sprawdzenie przed null
.
Tak. Uzupełnienie: to mylić mnie przez jakiś czas też, zwłaszcza, że w C# można zrobić Ogień + = new MyDelegate (OnFire) lub Ogień + = OnFire; Ten ostatni wydaje się być prostszy, ale jest po prostu cukrem syntaktycznym dla pierwszego. –
@Nicholas Piasecki: Dzięki; Zaktualizowałem swoją odpowiedź, aby zauważyć, że (raczej użyteczny) skrót. –
Warto zauważyć, że dodanie delegata multiemisji i późniejsze anulowanie subskrypcji może przynieść niepoprawne wyniki, jeśli dowolna z metod w ramach tego delegata multiemisji jest również subskrybowana i subskrybowana indywidualnie. – supercat