2015-04-23 231 views
2

我所有我見過的在C#中的事件的樣本是觸發該事件被寫成注意到:觸發事件

PropertyChangedEventHandler handler = PropertyChanged; 
if(handler != null) 
    handler(this, new PropertyChangedEventArgs(propertyName)); 

那是什麼,只是寫之間的不同:

if(PropertyChanged != null) 
    PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
+4

原因是作爲問題的一部分陳述在這裏:http://stackoverflow.com/questions/786383/c-sharp-events-and-thread-safety還有一個鏈接到Eric Lippert的博客文章解釋它:http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx – Dirk

+1

@JenishRabadiya:它可以爲null。這是一個事件。 –

+0

@PatrickHofman是的你是對的。它來自'INotifyPropertyChanged'接口。 –

回答

4

在第二種情況下,如果您正在運行多線程,則PropertyChanged的值可能會在if與invoke之間發生變異。不推薦。

您也可以嘗試初始化事件處理程序有一個空的處理程序是這樣的:

public EventHandler<PropertyChangeEventArgs> PropertyChanged = (s, e) => { }; 

,這意味着它永遠不會爲空,這樣你就可以只啓動它是。

+0

*這意味着它永遠不會爲空*除非您將其設置爲。不要忘記你可以在聲明事件的類中明確地將其設置爲null。 –

8

在你的第二個例子中,你調用PropertyChanged的獲得者兩次。在多線程環境中,可能會在兩次調用之間更改值。

在第一個示例中,通過先製作本地副本,可以防止這種情況發生。

+0

但是在第一種情況下(代碼片段),如果某個線程爲'PropertyChanged'分配空值,則不會將其分配給'處理程序'實例,因爲委託的行爲類似於引用類型。 –

+0

@JenishRabadiya處理程序仍然會指向最初的代表。將代理想象成一個數組(要調用的方法)。如果將先前指向數組的一個變量設置爲空,則不會更改指向同一數組的另一個變量。 – GvS

+0

當我閱讀[msdn文檔](https://msdn.microsoft.com/en-us/library/ms173172.aspx)時,這似乎讓我感到困惑。文檔引號「委託類型派生自.NET Framework中的委託類」,代表是可能的參考類型。 –