繁体   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