簡體   English   中英

.NET委托是否用於事件?

[英]Are .NET delegates used for events?

我有點困惑,我知道委托就像函數指針一樣,它們用於將函數作為參數傳遞給方法。

這如何適合事件模型?

呼叫:

myButton.OnClick += new .....();

在事件發生時,內部只是將方法/函數作為參數傳遞,並且所有訂閱者都會收到有關該事件的通知嗎?

看看這個

好奇心很幸福

當你這樣做時:

myButton.OnClick += new ...();

您正在將您的委托添加為該事件的訂閱者。 稍后提出事件時,將調用所有訂閱者(不保證訂單)。 這稱為多播委托。 它有點像一個函數指針,可以讓它“指向”多個函數。

請注意,現在您不需要顯式創建委托,您只需使用方法名稱:

myButton.OnClick += MethodName;

並且不要忘記您可以(並且應該, 為什么 )取消訂閱您訂閱的事件以防止泄漏:

myButton.OnClick -= MethodName;

該活動有兩個運營商; 添加和刪​​除。 添加事件處理程序時(如示例所示),事件將獲取對該方法的引用,並將其添加到其訂閱事件處理程序列表中。 引發事件時,它將遍歷列表並調用其中的方法。

實際上, 委托就像一個函數指針。 一個區別是委托由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中添加兩個委托。 也可以從多播委托中刪除委托。 調用時,多播委托將調用其所有子委托。 這可能會帶來其他問題,但我會偏離原來的問題。


另一方面, 事件是完全不同的事情。 事實上,事件是具有特殊訪問者的屬性。 常規屬性具有以下兩個訪問器: getset 事件有這兩個: 添加刪除

add訪問器將事件中的當前委托與新委托合並為多播委托。 刪除訪問器將執行相反的操作。

考慮到這一點,很容易理解為什么C#設計者選擇了+ =- =運算符。 我的意思是以下兩行在某種程度上是等價的(如果你忽略了第二行)。

myButton.OnClick += newEventHandler;
myButton.OnClick = myButton.OnClick + newEventHandler;

該事件,在按鈕Click的情況下是“Click”事件,在此處充當“函數指針”。 這意味着,當您使用+ =語法向其添加方法時,您實際上是將Click Function Pointer POINT設置為您的函數。 因此,單擊該按鈕時,Click Function Pointer將調用其指向的所有函數。 說得通?

事件是基於委托的屬性。

它包裝了一個私有(和隱藏)委托成員。

我同意所有的說法,我只想加上我的兩分錢。

如果我要重新編寫文檔,我會說委托是指針和語言的一部分,而事件是框架的一部分,允許您使用windows-event-and-messaging-pump的工具。 當您嘗試在ASP.NET下使用EVENTS並需要等待事件時,您會注意到這一點。 (更多信息http://discuss.joelonsoftware.com/default.asp?joel.3.456478.15 )我的問題是MultiCast Delegates是介於兩者之間的版本,因此難以區分和清除它們。

delegate是指向函數的指針MultiCastdelegate是一個名稱下聚合的委托列表

event是一個修飾符,它以不同的方式執行一些操作1.在調用者的ThreadContext下運行(請參閱BackgroundWorker和AsyncOperationManager)。 2.事件可以添加到接口(澄清OO連接)

委托1.在監聽器2的上下文中運行。不能添加到接口

閱讀http://blogs.msdn.com/b/jaybaz_ms/archive/2004/06/17/158636.aspx ,了解有關事件和競爭條件的更多數據。

Button有一個私有的“多播委托”字段,你使用+ =和 - =運算符的公共屬性就像“Click”是一種自動生成的方法來管理該私有字段的狀態。

當按鈕在內部引發click事件時,它正在調用該私有多播委托,它將調用它當前知道的所有委托。


首次實現您自己的事件時,此系統可能會造成混淆,因為相同的標識符“EventName”指的是您的類中的一個內容(私有多播委托字段)和類外的另一個內容(該字段的公共管理機制) )。

“事件”是多播委托。 例如:

public class ObservableObject : INotifyPropertyChanging, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler   PropertyChanged;
}

INotifyPropertyChanged的實現者包括public event PropertyChangedEventHandler PropertyChanged PropertyChangedEventHandler是一個聲明為的委托:

public delegate void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs e);

那么這個修飾符事件在做什么呢? 首先,只有包含實例才能調用它。 第二個客戶端只能向/從實例添加/刪除處理程序。

編譯器添加了兩個方法add_PropertyChanged和remove_PropertyChanged編譯器將成員標記為私有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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