扣响C#之门笔记---第十六章

16.1 委托

(1)委托使用关键字delegate 申明,它实际上是定义了一种数 据类型(“函数类型”),明确规定了函数的参数类型 和返回值类型,(一般用委托来代替参数,返回值的相同的一类多个函数);

(2)当需要将具体某个函数作为参时候,就先要将它转换为委托的实例;

(3)调用时候,直接将委托实例,传递给定义函数即可;

(4)在新版本的.NET中,  我们可以直接传递函数名称,省去实例化委托的过程;

 

eg:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Test01
{
    class Program
    {
        delegate void AnimalPlay(string name); //(2)为三个函数定义一个委托

        static void Run(AnimalPlay a, string name)//(3)定义使用这个三个函数作为参数(委托)的函数
        {
            a(name);
        }

        static void DogPlay(string name)   //(1)定义三个相同签名的函数 ,函数1
        {
            Console.WriteLine("Hello,Iam "+name+"!");
            Console.WriteLine("****DogPlay****");
        }

        static void CatPlay(string name)  //函数2
        {
            Console.WriteLine("Hello,Iam " + name + "!");
            Console.WriteLine("****CatPlay****");
        }

        static void LionPlay(string name) //函数3
        {
            Console.WriteLine("Hello,Iam" + name + "!");
            Console.WriteLine("****LionPlay****");
        }

        static void Main(string[] args)
        {
            AnimalPlay a = new AnimalPlay(DogPlay);//(4)申明一个委托变量,并实例化;
            Run(a, "soopy");                      //(5)传递委托实例给函数
            Console.ReadKey();
            a = new AnimalPlay(CatPlay);
            Run(a, "kity");
            Console.ReadKey();
        }
    }
}

16.2 多播委托

(1)可以向一个委托注册多个函数,我们把包含多个函数的委托称为多播委托;(所有被委托的函数都存储在多播委托的调用列列表中,调用多播委托时候,会按顺序依次调用列表中的所有函数(如果一个函数多次注册,就会多次执行));

(2)向多播委托注册函数的语法为:(就是复合运算符+=,等价于a=a+new AnimalPlay(DogPlay))

(3)从多播委托删除函数的语法为:(就是复合运算符-=,等价于a=a- new AnimalPlay(DogPlay))

(4)多播委托的返回值只能为void(如果有返回值,应该返回那个函数的值呢?)

eg:

        static void Main(string[] args)
        {
            AnimalPlay a=null;             //申明委托变量   
            a += new AnimalPlay(DogPlay);  //添加注册函数,等价于 a=a+ new AnimalPlay(DogPlay);
            a += new AnimalPlay(CatPlay); //添加注册函数
            a += new AnimalPlay(LionPlay);//添加注册函数
            a -= new AnimalPlay(LionPlay);//删除注册函数等价于 a=a- new AnimalPlay(DogPlay);
           
            Run(a,"");
            Console.ReadKey();        
        }

 

16.3 匿名函数:

(1) 匿名函数 可以直接直接把“代码块”直接注册给 委托实例,而不需要事先定义函数;

namespace Test03
{
    class Program
    {
        delegate void mydelegate(string s);     //(1)定义委托
        static void Main(string[] args)
            {
                 mydelegate f = null;          //(2)使用匿名函数直接实例化一个委托对象(注意写法)
                 f = delegate(string s) 
                 {  
                   Console.WriteLine(s);
                   Console.ReadKey();  
                  };

               f("zhangkaineng");          //(3)使用委托
        }
    }
}

(2)匿名函数不仅可以使用自己方法内部的变量,也可以使用代码块外(宿主函数)定义的变量;

宿主变量被匿名函数使用,称之为宿主变量被匿名函数捕获(被捕获的变量的生存周期将延迟到委托销毁)

eg

namespace Test04
{
        class Program
        {
            delegate void mydelegate(int i,int j ); //定义委托
            static void Main(string[] args)
            {
                int i = 10000;                  //宿主变量
                mydelegate f = null;         
                f = delegate(int h,int j)
                {
                    Console.WriteLine(i);      //使用宿主变量
                    Console.WriteLine(h);     
                    Console.WriteLine(j); 
                    Console.ReadKey();
                };

                f(9,8); 
            }
        }
    }

  16.4 事件

事件就是委托的对象

(1)触发事件的对象称之为事件发送者(EventSender),响应事件的对象称之为事件接收者(EventReceiver)

比如说:按钮就是一个事件发送者,而响应按钮的窗体就是事件的接收者;

(2)事件机制过程与原理:

  //(1)事件处理代码 button1_Click

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("点击");
           
        }

//(2)事件处理代码的委托EventHandler
           public delegate void EventHandler(object sender, EventArgs e);

// (3)  委托的实例对象 事件 Click;
         public event EventHandler Click;
          
//(4)强事件注册到 事件上

         this.button1.Click += new System.EventHandler(this.button1_Click);

//(5) 触发事件
    
       mybutton.Click(this,e);

(3)自定义事件

(a)定义被委托函数(处理方法)

(b)定义方法对应的委托

(c)定义委托对应的对象(即事件)

(d)将被委托的函数注册到委托对象(事件上)

(f)引发事件

 class Program
    {
        static void Main(string[] args)
        {
            dog d = new dog();
            host h = new host(d);
            
            d.OnAlam();
           Console.ReadKey();
        }
    }

    class dog
    {
        //(2)定义方法对应的委托
        public delegate void AlarmHander(object sender, EventArgs e);
        //(3)定义委托对应的对象(即事件)
        public AlarmHander Alam;


        //(5)引发事件
        public void OnAlam()
        {
                     
                this.Alam(this,new EventArgs());
            
        }
        int i;
    }

    class host
    {
        // (1)定义被委托函数(处理方法)
        public void HostAlm(object sender, EventArgs e)
        {
            Console.WriteLine("抓住小偷");
        }
           //(4)将被委托的函数注册到委托对象(事件上)
        public host(dog d)
        {
            d.Alam += new dog.AlarmHander(HostAlm);
        }
        int i;

    }

(4)C#定义了100多个事件参数类,他们都继承于EventArgs
(5)可以重新定义EventArgs 类,此类可用于 事件触发者向订阅者 传递参数

 class Program
    {
        static void Main(string[] args)
        {
            
            dog d = new dog();
            host h = new host(d);
            d.dogjok(2);
            Console.ReadKey();
        }
    }

    //(1)C#定义了100多个事件参数类,他们都继承于EventArgs
    //(2)可以重新定义EventArgs 类,此类可用于 事件触发者向订阅者 传递参数
    public class AlamEventArgs:EventArgs
    {
      public  int number;
        public AlamEventArgs(int i)
        {
            this.number = i;
        }
    }

    class host
    {
        //将传递过来的参数取出使用
        public void hosthand(object o,AlamEventArgs e)
        {
            if (e.number < 2)
            {
                Console.WriteLine("抓住住小偷");
            }
            else
            Console.WriteLine("人太多 报警");
        }
        public host(dog d)
        {
            d.alm += new dog.hosthander(hosthand);
        }
    
    }

    class dog
    { 
      public delegate void hosthander (object o,AlamEventArgs e);
      public event hosthander alm;

      public void dogjok(int i)    //触发者产生参数i 通过构造函数将此值保存到EventArgs对象中
      {
          alm(this, new AlamEventArgs(i));  
      }


    }

 

 

 

 

 

posted on 2016-07-28 23:50  JUstForU  阅读(223)  评论(0)    收藏  举报

导航