技术开发 频道

关于.NET 中的Event机制


【IT168技术文档】

  使用.NET也有些日子了, 但对event这个东西一直没有去深入认识. 这两天因为想在DataGridView的cell里实现一个AutoComplete的功能, 趁机了解了一下, 下面贴上一点心得.

  Event机制其实是一个典型的Observer pattern: Publisher抛出一个事件, 所有订阅了该事件的Subscriber对此做出各自的响应.
  简单看下这个过程:

  Publisher:
public class Publisher { //Publisher exposes an event for subscribers. public event EventHandler OnPublish; public void InvokeMe(EventArgs e) { //Publisher trigger this event. if (OnPublish != null) OnPublish(this, e); } }
  Subscriber:
public class Subscriber { private Publisher m_Pub; //Subscriber expose a property to hook up a publisher's event. public Publisher MyPublisher { get { return m_Pub; } set { m_Pub = value; m_Pub.OnPublish += PublishHandler; } } //Subscriber's behavior to publisher's event. private void PublishHandler(object sender, EventArgs e) { Console.WriteLine(string.Format("Subscriber response to {0}",sender.ToString())); } }
  跑一下:
static void Main(string[] args) { Publisher publisher = new Publisher(); Subscriber subscriber = new Subscriber(); //Subscriber subscribe a publisher. subscriber.MyPublisher = publisher; //Trigger publisher's event. publisher.InvokeMe(new EventArgs()); Console.ReadLine(); }
  使用reflector 查看源代码, 发现CLR自动为Publisher类生成了一个EventHandler类型的成员:
  private EventHandler OnPublish;

  以及两个操作方法:
public void add_OnPublish(EventHandler value) { this.OnPublish = (EventHandler) Delegate.Combine(this.OnPublish, value); } public void remove_OnPublish(EventHandler value) { this.OnPublish = (EventHandler) Delegate.Remove(this.OnPublish, value); }
  看起来OnPublish和普通的delegate对象使用上并没有什么区别. 至此,有了一个疑问: 既然使用delegate就可以实现整套Event机制了, 那么event关键字的意义何在呢?

  我觉得是为了代码可读性. 一个被event修饰的delegate类型更加醒目, 提示着这个delegate类型的用途. 另外编译器会为event关键字修饰的delegate类型自动生成成员变量, 使代码看起来更加简洁直观. 不知道还有没有什么历史原因, 暂且就先认为是这两条吧.

  至此, 整个Event机制比较明了了, 简单说来, 就是subscriber把自己的函数地址赋给了一个特定的publisher的函数指针变量而已. 而在.NET Framework中, 这些地址就是一个个delegate对象了.
0
相关文章