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

□ 通过委托执行方法

    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. How to Create UML in Markdown

    Import yuml class format ![](http://yuml.me/diagram/boring/class/[...]) Create your own class Person ...

  2. 更改MySQL密码

    #安装MySQL5.7参考:https://blog.csdn.net/qq_23033339/article/details/80872136#MYSQL的基础操作参考:https://www.cn ...

  3. java中import详解

    前言 import与package机制相关,这里先从package入手,再讲述import以及static import的作用. package package名称就像是我们的姓,而class名称就像 ...

  4. 我们来说说self.setinterval

    学了js的你,肯定知道setInterval方法是按照指定的周期(以毫秒计)来调用函数或计算表达,setInterval方法会不停地调用函数,直到clearInterval被调用或窗口被关闭,这个se ...

  5. 20175204 张湲祯 2018-2019-2《Java程序设计》第七周学习总结

    20175204 张湲祯 2018-2019-2<Java程序设计>第七周学习总结 教材学习内容总结 -第八章常用实用类要点: 一.String类: 1.String类所在的包:java. ...

  6. React(17)异步组件

    26.异步组件当在React里使用异步组件时,核心知识是两个: webpack 如何异步加载其他模块:通过 require(['xxx'], function(module){})来实现:React ...

  7. python把列表前几个元素提取到新列表

    需要添加几个就循环几次   list = ['a','b','c','d','e'] new_list = [] for i in range(3): print(list[i]) new_list. ...

  8. 【interview】汉诺塔学递归

    https://www.cnblogs.com/yanlingyin/archive/2011/11/14/2247594.html https://www.cnblogs.com/dmego/p/5 ...

  9. web开发-前后端分离原理

    前言 前后端分离已成为互联网项目开发的业界标准使用方式,通过Nginx+Tomcat的方式(也可以中间加一个Node.js)有效的进行解耦,并且前后端分离会为以后的大型分布式架构.弹性计算架构.微服务 ...

  10. 爬取json Swaggerui界面

    对一个静态的网页进行爬取. 要获取的内容分别为 paths 标签下的 1./quota/开头的路径 2. get 这样的httpmode 3 description对应的描述 4 summary 5 ...