博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
快速理解C#高级概念(二) 事件与委托的区别
阅读量:5124 次
发布时间:2019-06-13

本文共 2927 字,大约阅读时间需要 9 分钟。

根据上篇博文的反响我想向大家说明,因为本人时间有限加上才疏学浅,无法写出面面俱到的博文。我只是把自己经历的觉得有些意义的技术点分享出来,希望大家见谅。当然,我不会让大家走上歧途的。所有示例都是亲测。

今天我想讨论一下事件与委托之间的联系。很多人说,事件即委托。真的是这样吗?那么微软为何又要定义事件与委托两个概念呢?

其实事件即委托,在我看来不如这样解释:事件是封装过的委托实例。也就是说,事件是面向对象的产物,它是封装性比较典型的示例。

首先我们来看一下事件的定义以及调用:

 

//定义委托    public delegate int MathHandle(int a, int b);    public class Test    {        //定义事件        public event MathHandle MathEvent;        public int Add(int a, int b)        {            return a + b;        }        public void Operation(int a, int b)        {            Console.WriteLine(this.MathEvent(a, b));        }    }    [TestClass]    public class UnitTest1    {        [TestMethod]        public void TestMethod1()        {            Test t = new Test();            //为事件方法队列添加方法            t.MathEvent += new MathHandle(t.Add);            t.Operation(1,2);//此处如果调用t.MathEvent(1,2)会编译错误;        }    }

执行结果:

我们再看看,如果我们将使用委托来实现上述方法:

//定义委托    public delegate int MathHandle(int a, int b);    public class Test    {        public MathHandle MathEvent;        public int Add(int a, int b)        {            return a + b;        }    }    [TestClass]    public class UnitTest1    {        [TestMethod]        public void TestMethod1()        {            Test t = new Test();            //为委托队列添加方法            t.MathEvent += new MathHandle(t.Add);            Console.WriteLine(t.MathEvent(1, 2));//委托可以直接在实例外部执行。        }    }

执行结果:

从上面示例我们看到,同一个方法你可以使用委托来调用,你也可以使用事件来调用。那究竟有何不同?

其实事件就是一个狭义的委托,也就是事件是一个用于事件驱动模型的专用委托.你可以在客户代码中直接调用委托来激发委托指向的函数,而事件不可以,事件的触发只能由服务代码自己触发。也就是说在你的代码里委托你不但可以安排谁是它的调用函数,还可以直接调用它,而事件不能直接调用,只能通过某些操作触发。除此之此,事件拥有委托的所有功能,包括多播特性。即事件可以有多个事件处理函数,委托同样也可以是个多播委托.

希望能从这个小小的示例,向大家传达到事件与委托的区别。

下面再贴一个稍微复杂的示例:

public class Heater     {        private int temperature;        public void BoilWater()         {            for (int i = 1; i <= 100; i++)             {                temperature = i;                if (temperature > 95 && BoilEvent != null)                 {                    //执行委托,无需知道要执行哪些方法                    BoilEvent(temperature);                }            }        }        public delegate void BoilHandle(int param);        public event BoilHandle BoilEvent;//封装了委托    }    public class Alarm     {        public void MakeAlert(int param)         {            Console.WriteLine("Alarm:水温已经超过{0}度.",param);        }    }    public class Display    {        public void ShowMsg(int param)        {            Console.WriteLine("Display:水已烧开,当前温度{0}度.", param);        }    }    [TestClass]    public class UnitTest1    {        [TestMethod]        public void TestMethod1()        {            Heater heater = new Heater();            Alarm alarm = new Alarm();            heater.BoilEvent += alarm.MakeAlert;            heater.BoilEvent += new Display().ShowMsg;            heater.BoilWater();        }    }

 

更多WEB开发技术请加群:Asp.Net高级群 号码:261882616  博主以及同事和你共同探讨感兴趣的话题。

 

 

转载于:https://www.cnblogs.com/lilin123/archive/2012/12/20/2826514.html

你可能感兴趣的文章
js阻止事件冒泡的两种方法
查看>>
Java异常抛出
查看>>
[SQL Server 系] T-SQL数据库的创建与修改
查看>>
74HC164应用
查看>>
变量声明和定义的关系
查看>>
Wpf 之Canvas介绍
查看>>
linux history
查看>>
jQuery on(),live(),trigger()
查看>>
Python2.7 urlparse
查看>>
sencha touch在华为emotion ui 2.0自带浏览器中圆角溢出的bug
查看>>
【架构】Linux的架构(architecture)
查看>>
ASM 图解
查看>>
Date Picker控件:
查看>>
svn在linux下的使用(svn命令行)ubuntu 删除 新增 添加 提交 状态查询 恢复
查看>>
java处理url中的特殊字符%等
查看>>
你的第一个Django程序
查看>>
Tomcat免安装版的环境变量配置以及Eclipse下的Tomcat配置和测试
查看>>
Unity3D性能优化之Draw Call Batching
查看>>
grafana授权公司内部邮箱登录 ldap配置
查看>>
treegrid.bootstrap使用说明
查看>>