2010-02-17 32 views
6

właśnie przeglądanie i natknąłem się na to pytanie:obsługi zdarzeń metoda podnoszenia konwencja

Action vs delegate event

The answer from nobug zawarte ten kod:

protected virtual void OnLeave(EmployeeEventArgs e) { 
    var handler = Leave; 
    if (handler != null) 
    handler(this, e); 
} 

Resharper generuje również podobny kod przy użyciu „stworzyć podniesienie metoda "quick-fix.

Moje pytanie brzmi, dlaczego jest to linia konieczne ?:

var handler = Leave; 

Dlaczego jest to lepsze niż pisanie tego ?:

protected virtual void OnLeave(EmployeeEventArgs e) { 
    if (Leave != null) 
    Leave(this, e); 
} 

Odpowiedz

12

to lepiej, ponieważ istnieje niewielka możliwość, że staje się zerowa Leave po sprawdzeniu zerowym, ale przed wywołaniem (które spowodowałoby, że twój kod rzuciłby NullReferenceException). Ponieważ typ delegata jest niezmienny, jeśli po raz pierwszy przypiszesz go do zmiennej, ta możliwość zniknie; Twoja lokalna kopia nie zostanie zmieniona po Leave po wykonaniu cesji.

Pamiętaj jednak, że to podejście powoduje również problem w odwrotnej kolejności; oznacza to, że istnieje (malutka, ale istniejąca) możliwość, że program obsługi zdarzenia zostanie wywołany po odłączeniu od zdarzenia. Ten scenariusz powinien oczywiście być obsługiwany z wdziękiem.

5

W aplikacji wielowątkowej można uzyskać wyjątek odwołania zerowego, jeśli wywoływacz wyrejestruje się ze zdarzenia. Przypisanie do lokalnej zmiennej chroni przed tym.

Szanse, których nigdy nie zobaczysz (dopóki nie zrobi ci się najgorsze). Oto sposób patrzenia na to, że pokazuje problem ...

protected virtual void OnLeave(EmployeeEventArgs e) { 
    if (Leave != null) //subscriber is registered to the event 
    { 
    //Subscriber unregisters from event.... 
    Leave(this, e); //NullReferenceException! 
    } 
} 
+0

Tak. Wywołanie programu obsługi zdarzeń po wyrejestrowaniu go jest nieusuwalną rasą. NRE można łatwo naprawić. –

Powiązane problemy