zoukankan      html  css  js  c++  java
  • 委托和事件的区别和联系

    委托,英文叫Delegate。它和C或C++中的函数指针十分类似,或者说委托是高级的函数指针。它具有两大特点:面向对象,类型安全和可靠的。

    代码如下:

    namespace DelegateDemo

    {

        public delegate void SayHandler(string name);

        class Program

        {

            protected void SaySmt(string name)

            {

                Console.WriteLine("Hello " + name);

            }

            static void Main(string[] args)

            {

                Program p = new Program();

                //实例化委托

                SayHandler objSay = new SayHandler(p.SaySmt);

                objSay.Invoke("委托");

                //实例化委托

                SayHandler objSay2 = p.SaySmt;

                objSay2("委托");

     

                Console.ReadKey();

            }

        }

    }

    通过上面代码也可以看出,委托其实也是一种与class、interface等类似的数据类型。委托就是对被委托函数的一次封装,它可以实例化,它是通过delegate关键字进行声明的,从此可以看出委托是面向对象的。

    委托是类型安全的意思是指,委托的签名要和被委托的函数的签名一致,如果不一致,系统在编译时就会报错。而对于一般的函数指针来说,通常是在运行时才会发现这种错误。

    在C#中,事件就是当对象发生某些事情时,向该对象的客户提供通知的一种方法。.NET的事件模型建立在委托机制之上,它实现了对委托的封装。因此它是一种特殊类型的委托,更确切的说是一个多播委托(MultiDelegate)。意思是指可以将多个事件处理函数委托交由一个事件进行托管,即当事件引发时,会调用其中的每一个委托函数。下面以一个猫和老鼠的例子加以说明:当猫发出叫声的时候,老鼠就会对这个事件作出响应。

    namespace CatAndMouse

    {

        class Program

        {

            static void Main(string[] args)

            {

                Cat cat = new Cat("Caffee");

                Mouse mouse = new Mouse();

                mouse.SetCat(cat);

                cat.InvokeMew();

     

                Console.ReadLine();

            }

        }

        /// <summary>

        /// 声明一个叫声委托

        /// </summary>

        /// <param name="cat"></param>

        public delegate void MewHandler(Cat cat);

     

        public class Cat

        {

            public string Name

            {

                get;

                set;

            }

            public Cat(string name)

            {

                this.Name = name;

            }

            //声明事件

            public event MewHandler Mew;

            /// <summary>

            /// 事件触发函数

            /// </summary>

            /// <param name="words"></param>

            protected void OnCatMew()

            {

                if (Mew != null)

                {

                    Mew(this);

                }

            }

            /// <summary>

            /// 引发事件的方法

            /// </summary>

            public void InvokeMew()

            {

                OnCatMew();

            }

        }

     

        public class Mouse

        {

            private Cat hatedCat;

            public void SetCat(Cat cat)

            {

                this.hatedCat = cat;

                //将事件处理函数与事件绑定

                hatedCat.Mew += new MewHandler(cat_Mew);

            }

            //事件处理函数(与委托具有相同的签名)

            void cat_Mew(Cat cat)

            {

                Console.WriteLine(string.Format("Shit!{0} Cat is Coming,Let’s go!", cat.Name));

            }

     

        }

    }

    根据以上代码可知事件的大致实现流程:

    1、  声明事件源,即Cat对象

    2、  事件接收者,即Mouse类

    3、  定义引发事件,即InvokeMew()方法。

    4、  关联事件和事件处理方法,即hatedCat.Mew += new MewHandler(cat_Mew);

    5、  客户端调用引发事件,即cat.InvokeMew();

    同样道理,对于界面控件的系统事件来说,其实现代码大致如下:

    protected void Page_Load(object sender, EventArgs e)

            {

                Button1.Click += new EventHandler(Button1_Click);

            }

     

            void Button1_Click(object sender, EventArgs e)

            {

                //做相应的处理

            }

    其实现流程和上一实例一样,只是委托不用自己定义,系统已经自定义好了,为EventHandler,它要求它委托的函数有两个参数,一个是Sender,即事件源信息,另一个e为封装的具体消息内容。事件名称Click也是系统定义好的,因此使用起来比较方便。

  • 相关阅读:
    《七哥说道》第五章:入职惨做苦力,画饼一望无际
    《七哥说道》第四章:理想在远方,现实在流浪
    《七哥说道》第三章:志远淋雨怒辞职,误入保险黄老萍
    《七哥说道》第二章:初出茅庐之拜师学艺
    (十)redis源码解读
    (三十二)线上调优
    (三)栈
    (一)设计模式之代理模式
    Linux whereis、find和locate命令区别以及应用场景
    使用自定义注解和AOP管理shiro权限
  • 原文地址:https://www.cnblogs.com/net2012/p/3386458.html
Copyright © 2011-2022 走看看