zoukankan      html  css  js  c++  java
  • 快速理解C#高级概念事件与委托的区别

    本文转载自:http://www.cnblogs.com/lilin123/archive/2012/12/20/2826514.html

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

    今天我想讨论一下事件与委托之间的联系。很多人说,事件即委托。真的是这样吗?那么微软为何又要定义事件与委托两个概念呢?
    其实事件即委托,在我看来不如这样解释:事件是封装过的委托实例。也就是说,事件是面向对象的产物,它是封装性比较典型的示例。

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

    //定义委托
        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();
            }
        }


  • 相关阅读:
    解决:Could not resolve archetype org.apache.maven.archetypes
    Spring MVC配置MyBatis输出SQL
    Spring集成MyBatis 通用Mapper以及 pagehelper分页插件
    关于SpringMVC或Struts2接受参数接收不到的原因
    配置quartz启动时就执行一次
    ajaxFileUpload进行文件上传时,总是进入error
    spring mvc注入配置文件里的属性
    java中将一个文件夹下所有的文件压缩成一个文件
    flume failed to start agent because dependencies were not found in classpath
    ubuntu不能安装pip unable to install pip in unbuntu
  • 原文地址:https://www.cnblogs.com/zztong/p/6695152.html
Copyright © 2011-2022 走看看