三个相关的习语:事件,委托,事件处理程序。我总是对谁被“添加”给谁感到困惑。
event += handler
event += delegate
handler += delegate
据我所知:
让我更加困惑的是MSDN中的这个签名:
public delegate void EventHandler(Object sender, EventArgs e)
答案 0 :(得分:4)
"事件"实际上只是两个使用委托的方法的捷径 - add and remove accessors。默认情况下,编译器会在事件后面创建一个委托(如果您不编写自己的访问者)。
当您致电someEvent += aDelegate;
时,您正在调用该活动的add
访问者。通常,编译器会将此转换为对事件具有相同签名的委托的delegate +=
调用 - 类似于自动属性自动映射到支持字段的方式。这就是为什么事件看起来与代表如此相似。
让我更加困惑的是MSDN中的这个签名: public delegate void EventHandler(Object sender,EventArgs e)
此签名只是委托签名。从技术上讲,事件可以使用任何代表。但是,按照惯例,它总是需要两个参数 - 第一个是"发送者"引发事件的第二个是源自EventArgs
的类(如EventHandler
和EventHandler<T>
)。
答案 1 :(得分:3)
该事件添加了delegate
,它“指向”处理程序。
基本上,当引发event
时,将调用它所拥有的委托集合,结果将调用连接到这些委托的处理程序。
//declare delegate
public delegate void EventHandler( Object sender, EventArgs e)
//create event based on delegate
public event EventHandler evHandler;
//function to attach to handler
public static void Handler(object sender, EventArgs e) {}
attach eventhandler function through delegate to event.
event += new EventHandler(Handler);
答案 2 :(得分:-1)
以下是我的摘要(如果我错了请纠正我):
delegate
是指向方法的指针(instance \ static)
eventHandler
是具有特定签名的委托人(sender,eventArgs)
event
是访问任何类型委托的抽象,但按惯例,它通常是eventHandler
//We declare delegates as a new type outside of any class scope (can be also inside?)
public delegate retType TypeName (params...)
//Here we assign
public TypeName concreteDeleagteName = new TypeName (specificMethodName);
//Declaring event
//a. taken from http://stackoverflow.com/questions/2923952/explicit-event-add-remove-misunderstood
private EventHandler _explicitEvent;
public event EventHandler ExplicitEvent
{
add
{
if (_explicitEvent == null) timer.Start();
_explicitEvent += value;
}
remove
{
_explicitEvent -= value;
if (_explicitEvent == null) timer.Stop();
}
}
//or: b.auto event - the compiler creates a "hidden" delegate which is bounded to this event
public event TypeName eventName;
我想推荐一篇精彩的文章 Event Handling in .NET Using C# 。
所以我们只能附加(eventName):
eventName += new TypeName (specificMethodName);
相当于(_eventName是委托\ eventHandler):
_eventName += new TypeName (specificMethodName);