1.委托的含义:
      (MSDN)A delegate declaration defines a reference type that can be used to encapsulate a method with a specific signature.A delegate instance encapsulates a static or an instance method.Delegates are roughly similar to function pointers in C++;however,delegates are type-safe and secure.
      委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。
        
      我们可以这样理解委托:委托是函数的封装,它代表一“类”函数,它们都符合一定的签名:拥有相同的参数列表、返回值类型。同时,委托也可以看成是对函数的抽象,是函数的类,此时的实例代表一个具体的函数。

      2.事件的理解:
      C#使用委托模型来实现事件。事件生成者类中不用定义事件的处理方法;事件订阅者是那些希望在事件发生时得到通知的对象,它们定义将和事件委托关联的事件处理方法。当生成事件时,事件生成者通过调用事件委托“触发”事件,然后委托调用和它关联的事件处理方法。

      3.猫和老鼠的例子
首先,我们设定一个简单场景来说明,夜深人静,屋里有老鼠蹑手蹑脚的行动,且随时提防着猫,如果听到猫叫,老鼠闻声立即逃回洞里。这个场景可以抽象为事件的几个要素:
      猫和老鼠是两个对象,猫是事件生成者对象,猫叫是一个方法,引发Cry事件;老鼠是事件订阅者对象,它提供事件处理程序Run()方法;通过委托和事件实现了老鼠对猫动静的监听,结果是老鼠听到猫叫就逃跑。下面是完整的例子:

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click机器学习导论猫和老鼠的例子 猫和老鼠案例分析_处理方法_02猫和老鼠的例子(1)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //定义一个委托,用来关联的Cry事件处理方法

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public delegate void CryEventHandler();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //Cat类是事件的生成者,通过OnCry()方法引发Cry事件

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //但Cat类并不知道谁会监听Cry事件,以及如何理Cry事件,它只是告诉环境Cry事件发生了

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //通俗的解释是:猫叫了,但猫并不知道它的叫声对环境有什么影响

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class Cat

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //定义事件,表示猫叫

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public static event CryEventHandler Cry;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public Cat()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.WriteLine("Cat:I'm coming.");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public virtual void OnCry()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.WriteLine("Cat:MiaoMiao

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            if (Cry != null)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                Cry();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //Mouse类是事件的订阅者,定义了Cry事件发生时的处理方法Run()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //通俗的解释是:老鼠在夜间行动时,时刻都在堤防着猫,如果听到猫叫声马上离开

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class Mouse

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public Mouse()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Cat.Cry += new CryEventHandler(Run);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.WriteLine("Mouse:I go to find something,and I must always listen cat's crying.");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public void Run()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.WriteLine("Mouse:A cat is coming,I must go back!");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class Demo1

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public static void Main(string[] args)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Mouse mouse = new Mouse();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Cat cat = new Cat();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            cat.OnCry();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.ReadLine();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }      运行后控制台输出为:

Mouse:I go to find something,and I must always listen cat's crying.

      I'm coming. 

      Cat:MiaoMiao...

      Mouse:A cat is coming,I must go back!

 
      我们把猫和老鼠的场景设置复杂一点,假定有两种猫:一种是笨猫,它更本就追不上老鼠,所以老鼠即使听到它的叫声也不会逃走,对它描述为aBenCat;另一种猫就是能抓老鼠的猫了,让老鼠闻风丧胆,对它描述为smartCat。这时候老鼠听到猫叫就不会马上Run了,它要先判断来的猫是哪种猫,只有遇到的是smartCat时,老鼠才会Run。

      这就要求事件发生者除了告诉环境发生了Cry事件外,还要将一些额外的信息传递给事件的订阅者,以便订阅者根据不同情况执行不同的事件处理程序。EventArgs的类及其子类恰恰实现了这一功能。所有基于EventArgs的类都负责在发送器和接收器之间来回传递事件的信息。在大多数情况下,EventArgs类中的信息都被事件处理程序中的订阅者对象使用。但是,有时事件处理程序可以把信息添加到EventArgs类中,使之可用于发送器。下面是完整示例:

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click机器学习导论猫和老鼠的例子 猫和老鼠案例分析_处理方法_02猫和老鼠的例子(2)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //假定有两种猫:一种是笨猫,它更本就追不上老鼠,所以老鼠即使听到它的叫声也不会逃走,对它描述为aBenCat;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //另一种猫就是能抓老鼠的猫了,老鼠闻风丧胆,对它描述为smartCat

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //定义一个委托,用来关联的Cry事件处理方法

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public delegate void CryEventHandler(object sender,CryEventArgs e);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //继承EventArgs类,负责在事件发送器和订阅者之间传递事件的信息

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class CryEventArgs : EventArgs

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        private string description;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public string Description

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            get 

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{ return description; }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            set 

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{ description = value; }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //Cat类是事件的生成者,通过OnCry()方法引发Cry事件

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //但Cat类并不知道谁会监听Cry事件,以及如何理Cry事件,它只是告诉环境Cry事件发生了

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //通俗的解释是:猫叫了,但猫并不知道它的叫声对环境有什么影响

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class Cat

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //定义一个事件,表示猫叫

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public static event CryEventHandler Cry;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //猫的描述信息

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        private string description;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public string Description

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            get 

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{ return description; }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            set 

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{ description = value; }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public Cat(string description)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            this.description = description;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.WriteLine("Cat:" + this.description + " coming.");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public virtual void OnCry()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.WriteLine("Cat:MiaoMiao

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            //将事件的发送者和事件信息作为参数传递给事件处理函数

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            CryEventArgs e = new CryEventArgs();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            e.Description = this.description;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            if (Cry != null)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                Cry(this, e);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //Mouse类是事件的订阅者,定义了Cry事件发生时的处理方法Run()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //通俗的解释是:老鼠在夜间行动时,时刻都在堤防着猫,如果听到猫叫声马上离开

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class Mouse

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public Mouse()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Cat.Cry += new CryEventHandler(Run);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.WriteLine("Mouse:I go to find something,and I must always listen cat's crying.");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //老鼠听到猫叫声,会先判断是哪种猫,然后再采取下一步行动

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public void Run(object sender, CryEventArgs e)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            string catDescription = e.Description;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            //注释掉的这句效果是一样的

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            //string catDescription = ((Cat)sender).Description;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            if (catDescription.Equals("aBenCat"))

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                Console.WriteLine("Mouse:" + catDescription + ",I am not afraid!");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            else

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                Console.WriteLine("Mouse:" + catDescription + ",I must run!");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class Demo2

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public static void Main(string[] args)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Mouse mouse = new Mouse();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Cat cat1 = new Cat("aBenCat");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            cat1.OnCry();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Cat cat2 = new Cat("smartCat");

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            cat2.OnCry();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            Console.ReadLine();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }

      运行后控制台输出为:
      Mouse:I go to find something,and I must always listen cat's crying.
      Cat:aBenCat coming.
      Cat:MiaoMiao...
      Mouse:aBenCat,I am not afraid!
      Cat:smartCat coming.
      Cat:MiaoMiao...
      Mouse:smartCat,I must run!

      通过上面的两个示例可以看到,事件的本质是委托,事件发生时,会去执行通过委托指定的回调函数,但回调函数不是由事件的发生者指定,而是由事件的订阅者来指定的,这就形成了一种松耦合关系。
      事件和委托的关系让人迷惑,感觉是因为.NET中定义的事件多是由系统自动触发的,而不是像上面的例子在Main函数中调用了Cat.OnCry()方法。如System.Web.UI.Button类的Click事件,我们只要在客户端点击Button就自动触发了Click事件,并没有在Page类调用Button.OnClick()方法,实际上也不可以调用,因为该方法的访问权限是portected。但我们仔细研究Button类不难发现,当单击按钮时,处理窗体回发事件的RaisePostBackEvent()方法就会执行(感兴趣的朋友可以进一步研究为什么会执行),在Button类就是在这个方法中调用了OnClick方法。下面给出Button类中和Click事件相关的代码:

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click机器学习导论猫和老鼠的例子 猫和老鼠案例分析_处理方法_02Button类中Click事件

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //定义一个委托

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public delegate void EventHandler(object sender, EventArgs e);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    //Button类实现,省略了与Click事件无关的代码

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_03

    public class Button : WebControl, IButtonControl, IPostBackEventHandler

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_10

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_11

    

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //用作委托列表的关键字

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        private static readonly object EventClick;

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        static Button()

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            EventClick = new object();

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //添加或移除事件处理程序

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        public event EventHandler Click

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            add

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                base.Events.AddHandler(EventClick, value);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            remove

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                base.Events.RemoveHandler(EventClick, value);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //protected表明只能是自己或子类调用,不允许其它类调用

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        protected virtual void OnClick(EventArgs e)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            EventHandler handler = (EventHandler)base.Events[EventClick];

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            if (handler != null)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                handler(this, e);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13


机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        //处理窗体发送给服务器时引发的事件,即Click事件

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

        protected virtual void RaisePostBackEvent(string eventArgument)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

        

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            base.ValidateEvent(this.UniqueID, eventArgument);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            if (this.CausesValidation)

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_17

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_18

            

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_事件处理_12

{

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

                this.Page.Validate(this.ValidationGroup);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

            }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            //EventArgs.Empty表示没有事件数据的事件,等同于EventArgs类的构造函数

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_13

            this.OnClick(EventArgs.Empty);

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_机器学习导论猫和老鼠的例子_21

        }

机器学习导论猫和老鼠的例子 猫和老鼠案例分析_Click_36

    }