[英]Event handler raising method convention
我只是在瀏覽並遇到了這個問題:
來自nobug的答案包括以下代碼:
protected virtual void OnLeave(EmployeeEventArgs e) {
var handler = Leave;
if (handler != null)
handler(this, e);
}
使用“創建提升方法”快速修復時,Resharper也會生成類似的代碼。
我的問題是,為什么這條線是必要的?:
var handler = Leave;
為什么寫這個更好?:
protected virtual void OnLeave(EmployeeEventArgs e) {
if (Leave != null)
Leave(this, e);
}
它更好,因為在null檢查之后,但在調用之前, Leave
變為null的可能性很小(這會導致代碼拋出NullReferenceException
)。 由於委托類型是不可變的,如果你首先將它分配給變量,這種可能性就會消失; 轉讓后Leave
的任何更改都不會影響您的本地副本。
請注意,這種方法也會產生相反的問題; 它意味着事件處理程序在從事件中分離后會被調用(微小但存在)。 當然也應該優雅地處理這種情況。
在多線程應用程序中,如果調用者從事件中取消注冊,則可能會獲得空引用異常。 對局部變量的賦值可以防止這種情況發生。
可能你永遠不會看到這種情況(直到它傷到你最壞的情況)。 這是一種看待它的方式,顯示問題......
protected virtual void OnLeave(EmployeeEventArgs e) {
if (Leave != null) //subscriber is registered to the event
{
//Subscriber unregisters from event....
Leave(this, e); //NullReferenceException!
}
}
以下是Eric Lippert的精彩解釋:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.