Dot-Net

如何在 VB.NET 中引發事件之前檢查訂閱者

  • May 23, 2013

在 C# 中,您可以執行以下操作:

if (Changed != null)
   Changed(this, EventArgs.Empty);

但是你在 VB.NET 中做什麼呢?

RaiseEvent,但是是

RaiseEvent Changed(Me, EventArgs.Empty)

實際檢查是否有東西訂閱了該事件?

與它的 C# 等價物不同,RaiseEvent在 VB.NET 中,如果沒有偵聽器,則不會引發異常,因此沒有必要首先執行 null 檢查。

但是,如果你想這樣做,它有一個語法。您只需Event在事件名稱的末尾添加一個後綴即可。(如果你不這樣做,你會得到一個編譯器錯誤。)例如:

If ChangedEvent IsNot Nothing Then
   RaiseEvent Changed(Me, EventArgs.Empty)
End If

不過,就像我上面所說的那樣,我不確定這樣做是否有任何真正的好處。它使您的程式碼不習慣並且更難閱讀。我在這裡介紹的技巧並不是特別有據可查,大概是因為RaiseEvent關鍵字的全部意義在於在後台為您處理所有這些。這種方式更加方便和直覺,這是 VB.NET 語言的兩個設計目標。

您可能應該讓它自動處理的另一個原因是因為在使用 C# 方式時很難正確處理它。您顯示的範例片段實際上包含一個競爭條件,一個等待發生的錯誤。更具體地說,它不是執行緒安全的。您應該創建一個擷取目前事件處理程序集的臨時變數,然後進行空檢查。像這樣的東西:

EventHandler tmp = Changed;
if (tmp != null)
{
   tmp(this, EventArgs.Empty);
}

Eric Lippert 在這裡有一篇很棒的部落格文章,靈感來自這個 Stack Overflow 問題

有趣的是,如果您檢查使用該RaiseEvent關鍵字的反彙編 VB.NET 程式碼,您會發現它與上述正確的C# 程式碼所做的完全一樣:聲明一個臨時變數,執行空檢查,然後呼叫委託。為什麼每次都把你的程式碼弄得亂七八糟?

引用自:https://stackoverflow.com/questions/16711254