我读了很多材料,但我仍然不明白,有人可以解释一下吗?
我知道什么:
宣布一个事件:
public event MyEvent myEvent;
Vs以上。
声明EventHandler:
public EventHandler MyEventHandler;
虽然EventHandler是.NET中的关键字:
public delegate void EventHandler (Send object, EventArgs e);
所以,EventHandler是一个委托,而不是一个事件,因为它没有在关键字'event'中使用?
我什么时候应该使用'Event'和'EventHandler'?
答案 0 :(得分:5)
啊,事件与代表问题。我记得也有这个问题......
所以,假设你正在制作一个名为“猫”的课程,你想让你的人知道你的猫何时饿了。您可以通过以下两种方式之一来实现:通过在Cat类上公开委托或通过公开事件。
您可以将委托视为指向函数(或方法)的指针。所以我们假设有一个名为“Person”的类,它有一个名为FeedCat(Cat cat)
的方法。
代表方式
如果你的猫正在公开一个名为HungryDelegate
的委托,那么该人可以将委托指向他们的FeedCat
方法,这样当猫饿了时,就可以调用{{1这个人的方法。
这里的问题是,只有一个人可以养猫。假设您希望多人能够喂猫。人们可能忙于做其他事情,所以猫能够告诉多个人它很饿是很重要的。通过这种方式,人们会收到通知,他们可以在有机会时检查猫,看看是否有人喂猫,如果没有,则喂它。
救援活动:
事件基本上是一个代表列表(某种类型)。如果您在“Cat”类中公开FeedCat
事件,则多个人可以将指针(委托)添加到其Hungry
方法中。
如果他们喜欢,他们也可以删除指针(委托)到他们的FeedCat
方法。让我们说一个人搬出去,他们的妹妹正在照顾这只猫。此人可以从猫身上移除他们自己的FeedCat
功能的代理人,这样他们就不会再收到通知说猫咪饿了。
活动与多播代表?
从技术上讲,为了能够提供多个委托,您可以使用所谓的MultiCastDelegates而不是事件。它们是复合代表(链表或代表)。问题是,每个人都可以从外面弄乱他们。一个邪恶的人可以删除其他人的“FeedCat”代表,这只可怜的猫会饿死(或者必须学会狩猎)。
使用事件时,重要的是该人无法看到添加到事件中的其他人的代理,也无法删除它们或与它们交互(原则上)。
答案 1 :(得分:2)
公开(public
)字段
public EventHandler MyEventHandler;
是不良做法:人们可以轻易地破坏代码并输入一个小错误:
MyClass demo = new MyClass();
demo.MyEventHandler += MyMethod;
...
// Can you see the error? = instead of correct += ?
// MyMethod will not be called since this assignment
demo.MyEventHandler = MyReaction;
这就是为什么你应该使用 event 为此特别设计
public event EventHandler MyEventHandler;
如果我们尝试上一个demo
,我们会得到编译时错误:
MyClass demo = new MyClass();
...
demo.MyEventHandler = MyReaction; // <- doesn't compile, insist on +=
在极少数情况下,您可能需要显式的基于委托的字段,但这些字段应隐藏,例如,private
,而不是public
:
// We don't expose the field
private EventHandler m_MyEventHandler;
// ... But event:
public event EventHandler MyEventHandler {
add {
//TODO: extra logic on += operation
m_MyEventHandler += value;
}
remove {
//TODO: extra logic on -= operation
m_MyEventHandler -= value;
}
}