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

□ 通过委托执行方法

    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. JGUI源码:实现蒙版层显示(18)

    有的时候需要显示一个蒙版层,蒙版层显示的主要原理是在指定元素比如div上创建一个子元素div,设置absolute.宽高100%.设置z-index置于顶层,设置半透明效果,fadein,fadeou ...

  2. socket.io emit callback调用探秘

    socket.io https://socket.io/ https://socket.io/docs/ What Socket.IO is Socket.IO is a library that e ...

  3. python学习08

    python中的异常处理 1.格式 try 语句块 except else finally else 是如果try语句没有异常,就执行,否则不执行 finally 不管程序是否异常,都会执行. 2.异 ...

  4. python3 练手实例4 九九乘法口诀表

    for i in range(1,10): for j in range(1,i+1): print('{}*{}={}\t'.format(i,j,i*j),end='') print()

  5. 关于接口(Interface)

    接口,其实是指类之间约定的协议,可以包含方法.属性.事件和索引: 接口成员不允许使用访问修饰符号(public.private.protected.internal),所有的接口成员都是公共的. 接口 ...

  6. 一个老鸟发的公司内部整理的 Android 学习路线图

    基础工具部分: 中文手册,我猜测是Maven中文手册,可是我并没有找到这样的资源,欢迎知道的朋友告诉我: Android部分有 『第三方库集合』,我没能找到资源地址: 书籍我大多是给的豆瓣链接,如果觉 ...

  7. Input子系统(二)【转】

    转自:http://blog.chinaunix.net/uid-25047042-id-4192368.html 上一篇中粗略的分析了下input_dev,input_handle,input_ha ...

  8. python学习第32天

    # 使用模块操作进程# multiprocessing 一个多元化的进程模块# multiple 多元化 processing 进程 # 涵盖了和进程相关的几乎所有的内容# Process类 帮助你启 ...

  9. python学习第30天

    tcp协议的socket server 并发效果验证客户端的合法性socket模块还有一些其他的方法

  10. 洛谷P5284 [十二省联考2019]字符串问题 [后缀树]

    传送门 思路 设\(dp_i\)表示以\(i\)结尾的\(A\)串,能达到的最长长度. 然后发现这显然可以\(i\)往自己控制的\(k\)连边,\(k\)往能匹配的\(j\)连边,就是个最长路,只要建 ...