.NET委托是否用于事件?

时间:2009-07-16 13:03:31

标签: c# .net events delegates

我有点困惑,我知道委托就像函数指针一样,它们用于将函数作为参数传递给方法。

这如何适合事件模型?

通话:

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

在事件发生时,内部只是将方法/函数作为参数传递,并且所有订阅者都会收到有关该事件的通知吗?

9 个答案:

答案 0 :(得分:10)

看看这个

Curiosity is bliss

答案 1 :(得分:3)

当你这样做时:

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

您要将您的代理人添加为该活动的订阅者。稍后提出事件时,将调用所有订阅者(不保证订单)。这称为多播委托。它有点像一个函数指针,可以让它“指向”多个函数。

请注意,现在您不需要显式创建委托,您只需使用方法名称:

myButton.OnClick += MethodName;

不要忘记您可以(并且应该看到why)取消订阅您订阅的事件以防止泄漏:

myButton.OnClick -= MethodName;

答案 2 :(得分:2)

该活动有两个运营商;添加和删​​除。添加事件处理程序时(如示例所示),事件将获取对该方法的引用,并将其添加到其订阅事件处理程序列表中。引发事件时,它将遍历列表并调用其中的方法。

答案 3 :(得分:2)

实际上,委托很像函数指针。 第一个的区别在于委托由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;

答案 4 :(得分:1)

事件,在按钮Click的情况下是“Click”事件,在此处充当“函数指针”。这意味着,当您使用+ =语法向其添加方法时,您实际上是将Click Function Pointer POINT设置为您的函数。因此,单击该按钮时,Click Function Pointer将调用其指向的所有函数。有意义吗?

答案 5 :(得分:1)

事件是基于委托的属性。

它包装了一个私有(和隐藏)委托成员。

答案 6 :(得分:0)

Button有一个私有的“多播委托”字段,你使用+ =和 - =运算符的公共属性“Click”是一种自动生成的方式来管理私有字段的状态。

当按钮在内部引发click事件时,它正在调用该私有多播委托,它将调用它当前知道的所有委托。


这个系统在第一次实现你自己的事件时可能会让人困惑,因为同一个标识符“EventName”指的是你的类中的一个东西(私有多播委托字段)和你类之外的另一个东西(公共管理机制)对于那个领域)。

答案 7 :(得分:0)

'event'是多播委托。 例如:

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 编译器将成员标记为私有。

答案 8 :(得分:0)

我同意所有的说法,我只想补充两分钱。

如果我要重新编写文档,我会说 delegate是指针和语言的一部分 而event是框架的一部分,允许您使用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.事件可以添加到接口(澄清O-O连接)

代表 1.在听众的背景下运行 2.无法添加到接口

阅读http://blogs.msdn.com/b/jaybaz_ms/archive/2004/06/17/158636.aspx,了解有关事件和竞争条件的更多数据。