簡體   English   中英

事件處理程序提升方法約定

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM