我有點困惑,我知道代表就像函數指針一樣,它們用來將函數作爲參數傳遞給方法。.NET委託用於事件嗎?
這怎麼符合事件模型?
呼喚:
myButton.OnClick += new .....();
是在內部只是路過的方法/函數的參數在事件發生時,所有的用戶都收到該事件?
我有點困惑,我知道代表就像函數指針一樣,它們用來將函數作爲參數傳遞給方法。.NET委託用於事件嗎?
這怎麼符合事件模型?
呼喚:
myButton.OnClick += new .....();
是在內部只是路過的方法/函數的參數在事件發生時,所有的用戶都收到該事件?
看一看這個
的事件,在點擊一個按鈕的情況下是「點擊」事件中,充當「函數指針」在這裏。意思是,當你使用+ =語法向你的方法添加你的方法時,你基本上將點擊函數指針指向你的函數。因此,點擊按鈕時,點擊功能指針將調用其指向的所有功能。說得通?
該事件有兩個操作符;添加和刪除。當你添加一個事件處理程序(如你的例子)時,事件將獲得對該方法的引用,並將其添加到訂閱事件處理程序的列表中。當事件發生時,它將通過列表並調用其中的方法。
當你這樣做:
myButton.OnClick += new ...();
你將你的委託作爲一個用戶到該事件。當事件在晚些時候被提出時,所有訂戶都會被調用(沒有關於訂單的保證)。這被稱爲多播委託。它有點像一個函數指針,它允許它「指向」多個函數。
注意,現在你不需要明確創建委託,你可以只使用方法名:
myButton.OnClick += MethodName;
而且不要忘了,你可以(也應該看到why)取消訂閱您訂閱事件,以防止泄漏:
myButton.OnClick -= MethodName;
按鈕有一個私人「多播委託」字段和公共財產,如「點擊」您使用+ =和 - =運營商是一個自動生成的方式管理該私人領域的狀態。
當按鈕內部引發Click事件,則調用私有多播委託,將調用一切,它目前所知道的代表。
該系統可能會造成混淆第一個實現自己的活動的時候,因爲相同的標識符,「事件名稱」,指的是你的類中的一件事(私有多播委託場)和類之外的另一件事(該領域的公共管理機制)。
事件是基於委託的屬性。
它包裝一個私人(和隱藏)代表成員。
確實,代表非常像函數指針。 第一個區別在於委託由2個「指針」組成:一個函數指針和一個實例指針。毫不奇怪,Delegate類具有以下兩個屬性:
// Gets the method represented by the delegate.
public MethodInfo Method { get; }
// Gets the class instance on which the current delegate
// invokes the instance method.
public object Target { get; }
的第二區別是.NET代表可以是組播。可以在一個MulticastDelegate中添加兩個代表。也可以從多播委託中刪除委託。被調用時,多播委託將調用其所有子委託。這可能會導致其他問題,但我會偏離最初的問題。
一種事件,在另一方面,是完全不同的東西。事實上,一個事件是一個有特殊訪問者的財產。常規屬性有這兩個訪問者:得到和集合。事件有這兩個:加和刪除。
add accessor將當前委託與新委託組合到一個多播委託中。刪除訪問者將做相反的事情。
有考慮到這一點,這是很容易理解爲什麼C#設計人員挑選了+ =和- =運營商。我的意思是,以下兩行有些相同(如果你忽略第二個這樣的事實)。
myButton.OnClick += newEventHandler;
myButton.OnClick = myButton.OnClick + newEventHandler;
'event'是一個多播委託。 例如:
INotifyPropertyChanged的的public class ObservableObject : INotifyPropertyChanging, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
}
實現器包括public event PropertyChangedEventHandler PropertyChanged
。 PropertyChangedEventHandler是一個代表聲明爲:
public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);
那麼這個修飾符事件在做什麼? 首先只有包含的實例可以調用它。 第二個客戶端只能向/從實例中添加/刪除處理程序。
編譯器添加了兩個方法add_PropertyChanged和remove_PropertyChanged 編譯器將該成員標記爲私有。
我同意所有的說法,我只是想補充我的兩分錢。
如果我重新寫的文檔我要說的是, 代表是語言的指針和部分 而事件是一個框架,允許您使用的儀器的一部分,Windows的事件 - 和 - 消息泵。您在嘗試在ASP.NET下使用EVENTS時需要注意這一點,並且需要等待事件。 (欲瞭解更多信息,請致電http://discuss.joelonsoftware.com/default.asp?joel.3.456478.15) 我的問題是MultiCast Delegates是中間的一些版本,所以很難區分並清除它們。
委託是指向一個功能 MultiCastdelegate下一個名字聚集委託列表
事件是做一些不同的事情呼叫者的ThreadContext下 1.奔跑(見BackgroundWorker的和修正AsyncOperationManager)。 2.事件可以被添加到接口(澄清OO連接)
委託收聽者的上下文下 1.奔跑 2.不能被添加到接口
http://blogs.msdn.com/b/jaybaz_ms/archive/2004/06/17/158636.aspx閱讀有關事件和多個數據一般的競賽條件。
+1 - 良好的鏈接。 – 2009-07-16 13:16:58
好博客。我真的很喜歡Julien Couvreur。 – Kredns 2009-07-16 17:05:26
非常感謝,偉大的博客 – 2012-04-15 12:09:53