博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[.NET] C# 知识回顾 - Event 事件
阅读量:6002 次
发布时间:2019-06-20

本文共 4367 字,大约阅读时间需要 14 分钟。

C# 知识回顾 - Event 事件

【博主】反骨仔    【原文】  

  昨天,通过《》介绍了事件的定义及简单用法,今天我们通过控制台来看下“发布 - 订阅”的基本用法。

 

目录

 

一、发布基于 .NET 类库的事件

  .NET类库中的所有事件均基于  委托,定义如下:  

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

  你可以尝试手动输入  ,然后按下“F12”跳转到定义:

 

  .NET 2.0 引入了该委托的一个泛型版本,即 。

  【备注】虽然我们定义的事件可以基于任何自定的委托类型,但建议使用内置的 EventHandler 进行扩展。

 

二、采用 EventHandler 模式发布事件

  1.这里选择继承了 BCL 中的类 EventArgs,可以在事件的触发时进行数据的传递。

1     class MyEventArgs : EventArgs2     {3         public string Message { get; private set; }4 5         public MyEventArgs(string message)6         {7             Message = message;8         }9     }

 

  2.这里的第二个参数就是自定义的 MyEventArgs 类型,它继承了 EventArgs。 

delegate void MyEventHandler(object sender, MyEventArgs args);

 

  3.声明事件的几种形式:

    (1)如果没有自定义 EventArgs 类,你可以直接使用 C# 中默认提供的非泛型 EventHandler 委托。

public event EventHandler MyEvent;

 

    (2)如果使用的是非泛型的 ,并且写了一个自定义由  派生的类,可修改如下。

public event MyEventHandler MyEvent;

 

    (3)如果使用的是高级的泛型版本,就不需要自定义委托。你只需要简单地将事件类型指定为 EventHandler<MyEventArgs>,将尖括号中的内容替换为自己的类的名称。  

public event EventHandler
MyEvent;

 

三、一个简单的发布订阅 Demo

  下面的示例通过将自定义的 MyEventArgs 类和  进行演示:

This is MyEventArgs.cs  //事件参数
1     ///  2     /// 事件参数 3     ///  4     /// 
一个自定义的类:自定义事件的参数
5 class MyEventArgs : EventArgs 6 { 7 public string Message { get; } 8 9 public MyEventArgs(string message)10 {11 Message = message;12 }13 }

 

This is Publisher.cs  //发布者
1     ///  2     /// 事件发布者 3     ///  4     class Publisher 5     { 6         //声明一个泛型事件 7         public event EventHandler
MyEvent; 8 9 public void Publish()10 {11 Console.WriteLine("Publis is starting");12 13 //你可以在事件触发前写些代码14 15 OnMyEvent(new MyEventArgs(DateTime.Now.ToString()));16 }17 18 ///
19 /// 触发事件20 /// 21 ///
22 ///
虚方法,允许子类重写调用行为
23 protected virtual void OnMyEvent(MyEventArgs args)24 {25 //只有在事件订阅时(!= null),才触发事件26 MyEvent?.Invoke(this, args);27 }28 }

 

This is Subscriber.cs  //订阅者
1     ///  2     /// 订阅者 3     ///  4     class Subscriber 5     { 6         public Guid Guid { get; } 7  8         public Subscriber(Publisher publisher) 9         {10             Guid = Guid.NewGuid();11             //使用 C# 2 的语法进行订阅12             publisher.MyEvent += Publisher_MyEvent;13         }14 15         /// 16         /// 事件处理程序17         /// 18         /// 19         /// 20         private void Publisher_MyEvent(object sender, MyEventArgs args)21         {22             Console.WriteLine($"    Message is {args.Message}, Guid is {Guid}.");23         }24     }

 

This is Program.cs   //控制台,用于启动
1     class Program 2     { 3         static void Main(string[] args) 4         { 5             var publisher = new Publisher(); 6             var subscriber1 = new Subscriber(publisher); 7             var subscriber2 = new Subscriber(publisher); 8  9             //触发事件10             publisher.Publish();11 12             Console.WriteLine("OK!");13             Console.Read();14         }15     }

 

 

四、实现自定义事件访问器

  事件一种是特殊类型的多播委托,只能从声明它的类中进行调用。这些方法需要预先通过事件访问器添加到委托的调用列表中,事件访问器跟我们平时使用的属性访问器,特殊的是他们的名字,事件访问器被命名为 add 和 remove如果在代码中没有提供自定义的事件访问器,编译器会自动添加事件访问器。但在某些情况下,您可能需要提供自定义的行为。

1     class MyClass 2     { 3         ///  4         /// 锁 5         ///  6         private static object Locker = new object(); 7  8         ///  9         /// 接口10         /// 11         public interface IMyEvent12         {13             event EventHandler OnCall;14         }15 16         public class MyEvent : IMyEvent17         {18             /// 19             /// 触发前事件20             /// 21             event EventHandler PreEvent;22 23             public event EventHandler OnCall24             {25                 add26                 {27                     lock (Locker)28                     {29                         PreEvent += value;30                     }31                 }32                 remove33                 {34                     lock (Locker)35                     {36                         PreEvent += value;37                     }38                 }39             }40         }41     }

 

传送门

  《》

  《》

  《 》、《 》

  《》、《》

  《》

 


【参考】https://msdn.microsoft.com/zh-cn/library/w369ty8x(v=vs.80).aspx

【参考】微软官方文档

转载地址:http://qndmx.baihongyu.com/

你可能感兴趣的文章
c运算符和优先级
查看>>
TODO:一不顺眼就换字体Go之代码篇
查看>>
Linux设备驱动程序编写
查看>>
curl指令的使用
查看>>
为什么使用xfs
查看>>
THINKPHP 结合阿里大于发送短信
查看>>
网站故障排查常用命令
查看>>
Python setdaemon守护进程
查看>>
ubuntu10.04下安装LAMP
查看>>
sendmail+tls+java
查看>>
wget 用法
查看>>
Git配置以及命令总结
查看>>
cacti基础配置,附带软件包
查看>>
Centos 7 Saltstack自动化部署weblogic 12c
查看>>
自学sql之路,SQL 是用于访问和处理数据库的标准的计算机语言!
查看>>
Nginx基本配置
查看>>
[Windows Azure] How to use the Windows Azure Blob Storage Service in .NET
查看>>
LNAMP第二版(nginx 1.2.0+apache 2.4.2+php 5.4)
查看>>
MongoDB repl set权限认证配置步骤
查看>>
java学习笔记(1)
查看>>