Weź następującą klasę C #:
c1 {
event EventHandler someEvent;
}
Jeśli istnieje wiele prenumeraty c1
„s someEvent
imprezy i chcę je wszystkie usunąć, co jest najlepszym sposobem osiągnięcia tego celu? Weź również pod uwagę, że subskrypcje tego zdarzenia mogą być / są lambdami / anonimowymi delegatami.
Obecnie moim rozwiązaniem jest dodanie ResetSubscriptions()
metody do c1
tych zestawów someEvent
na null. Nie wiem, czy ma to jakieś niewidoczne konsekwencje.
EventHandlerList
, możesz to zrobić. Musiałbyś jednak rozpoznać te dwa przypadki - i może być wiele innych implementacji.hidden
.Dodaj metodę do c1, która ustawi „someEvent” na null.
źródło
Lepiej jest używać
delegate { }
niżnull
unikać zerowego wyjątku ref.źródło
List.Clear()
vsmyList = null
.Ustawienie zdarzenia na null wewnątrz klasy działa. Po usunięciu klasy należy zawsze ustawić zdarzenie na null, GC ma problemy ze zdarzeniami i może nie wyczyścić usuniętej klasy, jeśli ma wiszące zdarzenia.
źródło
Najlepszą praktyką w celu wyczyszczenia wszystkich subskrybentów jest ustawienie someEvent na wartość null przez dodanie innej metody publicznej, jeśli chcesz udostępnić tę funkcję na zewnątrz. Nie ma to niewidocznych konsekwencji. Warunkiem wstępnym jest pamiętanie o zadeklarowaniu SomeEvent ze słowem kluczowym „event”.
Proszę zobaczyć książkę - C # 4.0 w pigułce, strona 125.
Ktoś tutaj zaproponował użycie
Delegate.RemoveAll
metody. Jeśli go używasz, przykładowy kod może być zgodny z poniższym formularzem. Ale to jest naprawdę głupie. Dlaczego nie tylkoSomeEvent=null
wewnątrzClearSubscribers()
funkcji?źródło
Można to osiągnąć za pomocą metod Delegate.Remove lub Delegate.RemoveAll.
źródło
Koncepcyjny rozszerzony nudny komentarz.
Raczej używam słowa „obsługa zdarzeń” zamiast „zdarzenie” lub „delegat”. I użył słowa „wydarzenie” dla innych rzeczy. W niektórych językach programowania (VB.NET, Object Pascal, Objective-C) „zdarzenie” jest nazywane „komunikatem” lub „sygnałem”, a nawet ma słowo kluczowe „wiadomość” i określoną składnię cukru.
Aby odpowiedzieć na ten „komunikat”, odpowiada „program obsługi zdarzeń”, niezależnie od tego, czy jest to pojedynczy delegat, czy wielu delegatów.
Podsumowanie: „zdarzenie” to „pytanie”, „obsługa zdarzeń” to odpowiedź (odpowiedzi).
źródło
To jest moje rozwiązanie:
Musisz zadzwonić
Dispose()
lub użyćusing(new Foo()){/*...*/}
wzorca, aby wypisać się ze wszystkich członków listy wywołań.źródło
Usuń wszystkie zdarzenia, załóżmy, że zdarzenie jest typu „Działanie”:
źródło
GetInvocationList
.Zamiast ręcznie dodawać i usuwać wywołania zwrotne i mieć wszędzie zadeklarowaną grupę typów delegatów:
Możesz wypróbować to ogólne podejście:
źródło