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

 更新时间:2014年09月12日 12:24:36   投稿:shichen2014  
这篇文章主要介绍了C#中委托和事件的区别,并分别以实例形式展示了通过委托执行方法与通过事件执行方法,以及相关的执行流程与原理分析,需要的朋友可以参考下

本文实例分析了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#实现飞行棋小游戏

    C#实现飞行棋小游戏

    这篇文章主要为大家详细介绍了C#实现飞行棋小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • C#中SQL参数传入空值报错解决方案

    C#中SQL参数传入空值报错解决方案

    这篇文章主要介绍了C#中SQL参数传入空值报错解决方案,需要的朋友可以参考下
    2017-06-06
  • C# Nullable的使用小结

    C# Nullable的使用小结

    本文主要介绍了C# Nullable的使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • C#中基数排序算法的原理及实现

    C#中基数排序算法的原理及实现

    基数排序算法是一种非比较式的排序方法,通过分配和收集步骤对数字的每一位进行排序,学习基数排序有助于提高排序效率,解决特定问题,广泛应用于多个领域如数据分析和数据库索引建立等
    2024-10-10
  • C#画笔Pen保存和恢复图形对象的设置方法

    C#画笔Pen保存和恢复图形对象的设置方法

    这篇文章主要介绍了C#画笔Pen保存和恢复图形对象的设置方法,实例分析了画笔的保存save及恢复属性Restore的相关使用技巧,需要的朋友可以参考下
    2015-06-06
  • C#实现六大设计原则之依赖倒置原则

    C#实现六大设计原则之依赖倒置原则

    这篇文章介绍了C#实现六大设计原则之依赖倒置原则的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • C#使用Ado.net读取Excel表的方法

    C#使用Ado.net读取Excel表的方法

    这篇文章主要介绍了C#使用Ado.net读取Excel表的方法,涉及C#使用OLEDB操作Excel的方法,需要的朋友可以参考下
    2015-04-04
  • C#中参数数组、引用参数和输出参数示例详解

    C#中参数数组、引用参数和输出参数示例详解

    这篇文章主要给大家介绍了关于C#中参数数组、引用参数和输出参数的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • C#文件目录操作方法汇总

    C#文件目录操作方法汇总

    本文主要列举出C#文件和目录操作的一些方法,包括创建、移动、遍历目录,读写文件等方法,有需要的小伙伴可以学习一下。
    2016-04-04
  • C#实现的自定义邮件发送类完整实例(支持多人多附件)

    C#实现的自定义邮件发送类完整实例(支持多人多附件)

    这篇文章主要介绍了C#实现的自定义邮件发送类,具有支持多人多附件的功能,涉及C#邮件操作的相关技巧,需要的朋友可以参考下
    2015-12-12

最新评论