事件与事件处理程序

BIB*_*IBI 3 c# events eventhandler

我读了很多资料,但我还是听不懂,请问有人可以解释一下吗?

我知道什么:

声明一个事件:

public event MyEvent myEvent;
Run Code Online (Sandbox Code Playgroud)

VS.

声明EventHandler:

public EventHandler MyEventHandler;
Run Code Online (Sandbox Code Playgroud)

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

public delegate void EventHandler (Send object, EventArgs e);
Run Code Online (Sandbox Code Playgroud)

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

以及何时应使用“事件”和“事件处理程序”?

Dmi*_*nko 7

暴露一个 ( public)字段

 public EventHandler MyEventHandler;
Run Code Online (Sandbox Code Playgroud)

是一种不好的做法:一个小的错字很容易毁掉代码:

 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;  
Run Code Online (Sandbox Code Playgroud)

这就是为什么你应该使用专门为此设计的事件

 public event EventHandler MyEventHandler;
Run Code Online (Sandbox Code Playgroud)

如果我们尝试以前的demo我们会得到编译时错误

 MyClass demo = new MyClass();

 ...

 demo.MyEventHandler = MyReaction; // <- doesn't compile, insist on +=
Run Code Online (Sandbox Code Playgroud)

在极少数情况下,您可能需要显式基于委托的字段,但这些字段应该被隐藏,例如,是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;
  }  
} 
Run Code Online (Sandbox Code Playgroud)


ana*_*kic 6

啊,活动与代表问题。我记得也有这个问题...

因此,假设您正在上一门名为“猫”的课程,并且想让人们知道您的猫何时饿了。您可以通过以下两种方式之一进行操作:通过在Cat类上公开一个委托或通过公开一个事件。

您可以将委托视为函数(或方法)的指针。因此,假设有一个名为“ Person”的类,该类的方法为FeedCat(Cat cat)

委托方式


如果您的猫正在暴露一个名为的委托HungryDelegate,那么该人可以将该委托指向其FeedCat方法,这样,当猫饿了时,便可以通过一种FeedCat方法对该人进行调用。

这里的问题是,只有一个人可以喂猫。假设您希望有多个人能够喂猫。人们可能会忙于做其他事情,因此对于猫来说,能够告诉多个人饿了是很重要的。这样,人们就可以得到通知,他们可以在有机会的时候检查猫,看看是否有人已经喂过猫,否则就喂它。

救援事件:


一个事件基本上是(某种类型的)代表列表。如果Hungry在“ Cat”类上公开事件,则多个人可以将指针(委托)添加到其FeedCat方法。

FeedCat如果愿意,他们还可以删除指向其方法的指针(代理)。假设一个人搬了出去,他们的姐姐现在正在照顾这只猫。该人员可以FeedCat从猫中删除代表自己职能的代表,以使他们不再收到该死的猫饿了的通知。

事件与多播委托?


从技术上讲,为了能够提供多个委托,您可以使用所谓的MultiCastDelegates代替事件。它们是复合委托(链接列表或委托)。问题是,每个人都可以从外面惹恼他们。邪恶的人可以罢免其他所有人的“ FeedCat”代表,而可怜的猫会饿死(或必须学会狩猎)。

使用事件时重要的一点是,该人看不到添加到事件中的其他人的代表,也不能删除他们或与他们进行交互(原则上)。

  • 监听者 = 委托,观察者 = 事件 (2认同)