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

□ 通过委托执行方法

    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的源代码。

可见,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#中委托和事件的区别的更多相关文章

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

    这篇文章主要介绍了C#中委托和事件的区别,并分别以实例形式展示了通过委托执行方法与通过事件执行方法,以及相关的执行流程与原理分析,需要的朋友可以参考下 本文实例分析了C#中委托和事件的区别,分享给大家 ...

  2. 委托、Lambda表达式、事件系列06,使用Action实现观察者模式,体验委托和事件的区别

    在"实现观察者模式(Observer Pattern)的2种方式"中,曾经通过接口的方式.委托与事件的方式实现过观察者模式.本篇体验使用Action实现此模式,并从中体验委托与事件 ...

  3. c# 委托与事件的区别

    委托与事件的区别 委托和事件没有可比性,因为委托是数据类型,事件是对象(可以理解为对委托变量的封装.),下面说的是委托的对象(用委托方式实现的事件)和(标准的event方式实现)事件的区别.事件的内部 ...

  4. c#之委托和事件的区别

    1.什么是委托,这里就不做介绍了,如果想了解可以查看博客:http://www.cnblogs.com/xiaoxiaogogo/p/3571494.html 下面开始对事件进行介绍 1.定义事件以及 ...

  5. c#中委托和事件(转)

    C# 中的委托和事件 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 ...

  6. c#中委托和事件区别

    委托和事件相同的功能 class Dem5 { public Action deHandler; public event Action eveHa; public Dem5() { deHandle ...

  7. c#中委托和事件(续)(转)

    本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器.异常处理.超时处理和异步方法调用等内容. 为什么要使用事件而不是委托变量? 在 C#中的委托和事件 中,我提出了两个为 ...

  8. C#一些知识点:委托和事件的区别

    在C#中,委托和事件是比较容易混淆的两个知识点,本篇博客就记录一下委托和事件之间的区别. 定义上的区别 委托:委托实际上是一个类,用来表示一个函数,可以理解为C++中的函数指针. 事件:事件是一个修饰 ...

  9. C#中委托和事件

    目 录 将方法作为方法的参数 将方法绑定到委托 更好的封装性 限制类型能力 范例说明 Observer 设计模式简介 实现范例的Observer 设计模式 .NET 框架中的委托与事件 为什么委托定义 ...

随机推荐

  1. ACM-ICPC 2018 沈阳赛区网络预赛 F Fantastic Graph(贪心或有源汇上下界网络流)

    https://nanti.jisuanke.com/t/31447 题意 一个二分图,左边N个点,右边M个点,中间K条边,问你是否可以删掉边使得所有点的度数在[L,R]之间 分析 最大流不太会.. ...

  2. linux的sed命令(一)

    转自:https://www.cnblogs.com/ginvip/p/6376049.html Sed 简介 sed 是一种新型的,非交互式的编辑器.它能执行与编辑器 vi 和 ex 相同的编辑任务 ...

  3. Java 程序国际化

    相关类:  java.util.Locale   java.util.ResourceBundle  操作步骤: 可以新建一个包, 如 res , 添加 .properties 文件 在其中添加键值对 ...

  4. Coursera, Big Data 4, Machine Learning With Big Data (week 3/4/5)

    week 3 Classification KNN :基本思想是 input value 类似,就可能是同一类的 Decision Tree Naive Bayes Week 4 Evaluating ...

  5. js时间戳转日期

    //时间戳转日期 2017-04-30 13:20 //type=1--> 2017-04-30 13:20 //type=2-->2018年08月 //type=3-->2018- ...

  6. window C/C++ 简单的IDE编译器

    C-Free 官网链接: http://www.programarts.com/cfree_ch/download.htm

  7. docker安装mysql5.7

    查看镜像 docker search mysql 拉取镜像 docker pull mysql:5.7 运行镜像 docker run --name mysql -p 3306:3306 -e MYS ...

  8. hibernate查询出的实体,set值后,自动更新到数据

    如图: 故事背景:(p.s.我们的项目没有正确配置事务xml文件,未明原因导致事务定义的规则不起作用)获取一个资讯对象,调用该对象的set方法设置其中的content字段,然后把修改后的实体丢到官网首 ...

  9. LeetCode 解题总结

    1. 最长合法括号串 给定只包含'('和')'的字符串,找出最长合法括号串的长度. Example 1: Input: "(()"  Output: 2    Explanatio ...

  10. eclipse:插件安装总结

    1.SVN插件 首先安装SVNKIT,下载地址:https://svnkit.com/download.php 再安装Subclipse,这个在marketplace安装即可. 2.安装时报错:Una ...