专栏首页明丰随笔用.Net Framework标准使用事件

用.Net Framework标准使用事件

我们遵循.NET Framework标准事件模式的添加到类和结构中,.NET Framework 类库中的所有事件均基于 EventHandler 委托,定义如下:

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

.NET Framework 2.0 引入了泛型版本的委托 EventHandler<TEventArgs>。 定义如下:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);

尽管定义的类中的事件可基于任何有效委托类型,但一般还是建议使用EventHandler委托,因为这是.NET Framework的标准实现。标准里面主要有三个要素:

1. object sender: 声明事件成员的类。

2. EventArgs e: 所有订阅事件的对象可能关心的数据。

3. delegate void EventHandler(object sender, EventArgs e):事件背后的委托类型

标准实现看起来有点复杂,但是它有更多的好处,首先所有的事件编码规范一致了,有更多的可读性,然后程序也有了更大的灵活性。任何订阅了事件的对象,可以通过object sender参数来访问publisher对象,这是非常方便的。

使用EventHandler来实现事件

首先确定事件需要不需要自定义EventArgs。

1.不需要自定义EventArgs,可以直接声明发布类的事件成员:

public event EventHandler MyCustomEvent;

2.需要自定义EventArgs,先定义CustomEventArgs类型:

public class CustomEventArgs : EventArgs  
{  
    public CustomEventArgs(string s)  
    {  
        msg = s;  
    }  
    private string msg;  
    public string Message  
    {  
        get { return msg; }  
    }   
}

再自定义委托类型:

public delegate void CustomEventHandler(object sender, CustomEventArgs a);

最后声明发布类的事件成员:

public event CustomEventHandler RaiseCustomEvent;

但是如果使用泛型,可以不用自定义委托,可以直接声明发布类的事件成员:

public event EventHandler<CustomEventArgs> RaiseCustomEvent;

使用自定义 EventArgs 类和 EventHandler<TEventArgs> 作为事件类型来演示之前的步骤:

public class CustomEventArgs : EventArgs
{
  public CustomEventArgs(string s)
  {
    msg = s;
  }
  private string msg;
  public string Message
  {
    get { return msg; }
  }
}

public class Publisher
{
  public event EventHandler<CustomEventArgs> MyCustomEvent;
  public void DoSomething()
  {
    // Write some code that does something useful here
    // then raise the event. You can also raise an event
    // before you execute a block of code.
    Console.WriteLine("Publisher will send to subscribers.");
    // Make a temporary copy of the event to avoid possibility of
    // a race condition if the last subscriber unsubscribes
    // immediately after the null check and before the event is raised.
    EventHandler<CustomEventArgs> handler = MyCustomEvent;
    // Event will be null if there are no subscribers
    if (handler != null)
    {
      // Format the string to send inside the CustomEventArgs parameter
      var args = new CustomEventArgs("Did something");
      // Use the () operator to raise the event.
      handler(this, args);
    }
  }
}
public class Subscriber
{
  private string _id;
  public Subscriber(string id, Publisher pub)
  {
    _id = id;
    // Subscribe to the event using C# 2.0 syntax
    pub.MyCustomEvent += HandleCustomEvent;
  }
  // Define what actions to take when the event is raised.
  void HandleCustomEvent(object sender, CustomEventArgs e)
  {
    Console.WriteLine(_id + " received this message: {0}", e.Message);
  }
}

Main:

Publisher pub = new Publisher();
Subscriber sub1 = new Subscriber("sub1", pub);
Subscriber sub2 = new Subscriber("sub2", pub);
// Call the method that raises the event.
pub.DoSomething();

通过理解标准,然后我们动手实现,这样可以加深我们的理解。

本文分享自微信公众号 - 明丰随笔(liumingfengwx2),作者:刘明丰

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • WCF学习笔记 5

    服务通过 ServiceHost 进行寄宿。可以添加终结以暴露可被调用寻址和调用的资源。

    小蜜蜂
  • MVC和Webapi的区别

    Mvc主要用于构建网站,在后端实现了一套完整的MVC开发框架,默认使用Razor视图引擎。

    小蜜蜂
  • 使用.Net发电子邮件小结

    电子邮件是通过互联网发出去的,互联网中传输层协议有TCP/IP协议,邮件服务在基于TCP/IP底层协议之上的应用层实现SMTP、POP3、IMAP4等协议,通过...

    小蜜蜂
  • hdu 4009 Transfer water(最小型树图)

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/657...

    Gxjun
  • 聊聊flink的Broadcast State

    flink-core-1.7.0-sources.jar!/org/apache/flink/api/common/state/MapStateDescript...

    codecraft
  • 聊聊flink的Broadcast State

    flink-core-1.7.0-sources.jar!/org/apache/flink/api/common/state/MapStateDescript...

    codecraft
  • Take Zero-Touch Approach Lock Down IoT Device 采用零接触方式锁定物联网设备

    The demonstrated ability of hackers to penetrate IoT devices says more about the...

    银河1号
  • 视频物体分割--One-Shot Video Object Segmentation

    One-Shot Video Object Segmentation CVPR2017 http://www.vision.ee.ethz.ch/~cvl...

    用户1148525
  • POJ-1276-Cash Machine(多重背包)

    Cash Machine Time Limit: 1000MS Memory Limit: 10000K Total Submissions:...

    ShenduCC
  • 挖洞经验之代理不当日进内网

    大家好,我是STCX,应M姐姐之邀写一篇文章为咱们公众号做点贡献,那我就扯一下之前挖一个漏洞的经验。 ---- 正向代理和反向代理是forward/revers...

    ChaMd5安全团队

扫码关注云+社区

领取腾讯云代金券