Dot-Net
如何在 VB.NET 中引發事件之前檢查訂閱者
在 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# 程式碼所做的完全一樣:聲明一個臨時變數,執行空檢查,然後呼叫委託。為什麼每次都把你的程式碼弄得亂七八糟?