C#中委托和事件的区别实例解析

作者:shichen2014 时间:2022-07-03 09:28:39 

本文实例分析了C#中委托和事件的区别,分享给大家供大家参考之用。具体如下:

大致来说,委托是一个类,该类内部维护着一个字段,指向一个方法。事件可以被看作一个委托类型的变量,通过事件注册、取消多个委托或方法。本篇分别通过委托和事件执行多个方法,从中体会两者的区别。

一、通过委托执行方法


class Program
{
   static void Main(string[] args)
   {
     Example example = new Example();
     example.Go();
     Console.ReadKey();
   }
}
public class Example
{
   public delegate void DoSth(string str);
   internal void Go()
   {
     //声明一个委托变量,并把已知方法作为其构造函数的参数
     DoSth d = new DoSth(Print);
     string str = "Hello,World";
     //通过委托的静态方法Invoke触发委托
     d.Invoke(str);
   }
   void Print(string str)
   {
     Console.WriteLine(str);
   }
}

上述代码实现:

① 在CLR运行时,委托DoSth实际上就一个类,该类有一个参数类型为方法的构造函数,并且提供了一个Invoke实例方法,用来触发委托的执行。
② 委托DoSth定义了方法的参数和返回类型
③ 通过委托DoSth的构造函数,可以把符合定义的方法赋值给委托
④ 调用委托的实例方法Invoke执行了方法

但实际上让委托执行方法还有另外一种方式,那就是:委托变量(参数列表)


public class Example
{
   public delegate void DoSth(object sender, EventArgs e);
   internal void Go()
   {
     //声明一个委托变量,并把已知方法作为其构造函数的参数
     DoSth d = new DoSth(Print);
     object sender = 10;
     EventArgs e = new EventArgs();
     d(sender, e);
   }
   void Print(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
}

上述代码实现:

① 委托DoSth的参数列表和方法Print的参数列表还是保持一致
② 委托DoSth中的参数object sender通常用来表示动作的发起者,EventArgs e用来表示动作所带的参数。

而实际上,委托变量(参数列表),事件就是采用这种形式执行方法的。

二、通过事件执行方法


public class Example
{
   public delegate void DoSth(object sender, EventArgs e);
   public event DoSth myDoSth;
   internal void Go()
   {
     //声明一个委托变量,并把已知方法作为其构造函数的参数
     DoSth d = new DoSth(Print);
     object sender = 10;
     EventArgs e = new EventArgs();
     myDoSth += new DoSth(d);
     myDoSth(sender, e);
   }
   void Print(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
}

上述代码实现:

① 声明了事件myDoSth,事件的类型是DoSth这个委托
② 通过+=为事件注册委托
③ 通过DoSth委托的构造函数为事件注册委托实例
④ 采用委托变量(参数列表)这种形式,让事件执行方法

而且,通过+=还可以为事件注册多个委托。


public class Example
{
   public delegate void DoSth(object sender, EventArgs e);
   public event DoSth myDoSth;
   internal void Go()
   {
     //声明一个委托变量,并把已知方法作为其构造函数的参数
     DoSth d = new DoSth(Print);
     DoSth d1 = new DoSth(Say);
     object sender = 10;
     EventArgs e = new EventArgs();
     //为事件注册多个委托
     myDoSth += new DoSth(d);
     myDoSth += new DoSth(d1);
     myDoSth(sender, e);
   }
   void Print(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
   void Say(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
}

以上,通过+=为事件注册1个或多个委托实例,实际上,还可以为事件直接注册方法。


public class Example
{
   public delegate void DoSth(object sender, EventArgs e);
   public event DoSth myDoSth;
   internal void Go()
   {
     object sender = 10;
     EventArgs e = new EventArgs();
     //为事件注册多个委托
     myDoSth += Print;
     myDoSth += Say;
     myDoSth(sender, e);
   }
   void Print(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
   void Say(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
}  

三、通过EventHandler执行方法

先来看EventHandler的源代码。


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

可见,EventHandler就是委托。现在就使用EventHandler来执行多个方法。


public class Example
{
   public event EventHandler myEvent;
   internal void Go()
   {
     object sender = 10;
     EventArgs e = new EventArgs();
     //为事件注册多个委托
     myEvent += Print;
     myEvent += Say;
     myEvent(sender, e);
   }
   void Print(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
   void Say(object sender, EventArgs e)
   {
     Console.WriteLine(sender);
   }
}

总结:

① 委托就是一个类,也可以实例化,通过委托的构造函数来把方法赋值给委托实例
② 触发委托有2种方式: 委托实例.Invoke(参数列表),委托实例(参数列表)
③ 事件可以看作是一个委托类型的变量
④ 通过+=为事件注册多个委托实例或多个方法
⑤ 通过-=为事件注销多个委托实例或多个方法
⑥ EventHandler就是一个委托

相信本文所述对大家C#程序设计的学习有一定的借鉴价值。

标签:C#,委托,事件,区别
0
投稿

猜你喜欢

  • Java最长公共子序列示例源码

    2023-08-20 13:25:37
  • Android应用程序转到后台并回到前台判断方法

    2022-11-12 19:49:35
  • Java实现的并发任务处理实例

    2023-05-22 17:51:10
  • Java异步调用转同步方法实例详解

    2023-11-01 20:38:25
  • Java编程实现基于用户的协同过滤推荐算法代码示例

    2022-09-06 12:44:24
  • spring boot 集成 shiro 自定义密码验证 自定义freemarker标签根据权限渲染不同页面(推荐

    2023-07-28 17:39:16
  • 关于MVC与SpringMVC的介绍、区别、执行流程

    2023-11-28 02:25:56
  • C语言中队列的结构和函数接口的使用示例

    2022-01-08 06:56:40
  • spring retry实现方法请求重试的使用步骤

    2021-12-31 15:11:11
  • Spring IOC:CreateBean环节中的流程转换

    2022-06-10 12:28:31
  • Spring Boot mybatis-config 和 log4j 输出sql 日志的方式

    2021-05-31 22:13:20
  • Java Shutdown Hook场景使用及源码分析

    2023-05-19 06:01:30
  • kotlin之协程的理解与使用详解

    2023-10-21 15:55:57
  • C#的String和StringBuilder详解

    2022-06-21 09:51:31
  • Java面向对象基础知识之抽象类和接口

    2023-02-10 03:02:58
  • 一个JAVA小项目--Web应用自动生成Word

    2022-04-30 07:19:56
  • C#中List集合使用Max()方法查找到最大值的实例

    2023-12-01 08:03:32
  • C#中除去所有在HTML元素中标记

    2023-04-14 04:09:56
  • Java继承方法重写实现原理及解析

    2021-12-31 16:35:54
  • C#的内存回收代码

    2023-06-20 06:38:47
  • asp之家 软件编程 m.aspxhome.com