事件与EventHandler

时间:2017-10-19 07:18:21

标签: c# events eventhandler

我读了很多材料,但我仍然不明白,有人可以解释一下吗?

我知道什么:

宣布一个事件:

public event MyEvent myEvent;

Vs以上。

声明EventHandler:

public EventHandler MyEventHandler;

虽然EventHandler是.NET中的关键字:

public delegate void EventHandler (Send object, EventArgs e);

所以,EventHandler是一个委托,而不是一个事件,因为它没有在关键字'event'中使用?

我什么时候应该使用'Event'和'EventHandler'?

2 个答案:

答案 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;
  }  
}