Unity学习笔记:委托和事件

委托是一类行为抽象。是方法的引用,是一种数据类型

委托可以实现对方法的【间接】调用! 灵活=维护性好!

委托的定义:委托是一种数据类型;委托代表的是方法,当调用委托时就是调用了这个方法。

【委托能存储方法的地址{ 引用}】间接调用】

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

namespace DemoDelegate1
{
    //调用端
    class DelagateDemo1
    {
        static void Main(string[] args)
        {
            //步骤2:实例化委托(绑定f1方法)
            Handler handlerObj = new Handler(F1);
            //绑定A类的方法new Handler(A.F);

            //步骤3:调用委托
            handlerObj();
        }
       static  public void F1()
        { 
       
       }
       

       
    }
    //定义端
    //步骤1:声明委托,定义委托
    delegate void Handler();
    //delegate int CalHandler(int a, int b);
    class A
    {
        public static void F()
        {
            Console.WriteLine("委托的使用步骤");
        }

    }
   
    
}

使用案例↓

namespace 事件的使用案例_猫和老鼠
{
    class Program
    {
        static void Main(string[] args)
        {
            //猫 mao = new 猫();
            //老鼠 laoshu = new 老鼠();
            //mao.叫();
            //laoshu.逃跑();

            猫 mao = new 猫();
            老鼠 laoshu = new 老鼠();
            //步骤2:注册事件
            mao.叫+=new Handler(laoshu.逃跑);//添加老鼠跑行为
            //mao.叫-= laoshu.逃跑;
            //步骤4:
            mao.Notify();

            Console.Read();
        }
    }
    //1.1 定义一个委托
    delegate void Handler();//定义一个委托
    class 猫
    {
        //public void 叫()
        //{
        //    Console.WriteLine("miaomiao");
        //}
        //步骤1.2:定义事件
        //public event Handler 叫;
        public Handler 叫;
        //步骤3:触发事件 固有的写法
        public void Notify()
        { 
            if(叫!=null)//判断事件有没有执行
            {
                Console.WriteLine("miaomiao");
                叫();//调用事件的方法
            }
        }

    }
    class 老鼠
    {

        public void 逃跑()//老鼠逃跑行为
        {
            Console.WriteLine("jiji。。。。");
        }
    }
}

多播委托:一个委托对象关联多个方法 只返回最后方法的结果↓

所以:委托有返回值不适合多播执行!委托无返回值适合多播执行

namespace DemoDelegate2
{
    //调用端
    class DelagateDemo1
    {
        static void Main(string[] args)
        {
            //步骤2:实例化委托
            CalHandler handlerObj = new CalHandler(Add);
            handlerObj = handlerObj + new CalHandler(Divide);
            //步骤3:调用委托
            int re=handlerObj(6,2);
        }
       static  public int Add(int a,int b)
        {
            return a + b;
       }
       static public int Divide(int a, int b)
       {
           return a/b;
       }   
       
    }
    //定义端
    //步骤1:声明委托,定义委托   
    delegate int CalHandler(int a, int b);
   
    
}

实例化委托多种写法

委托的使用步骤:三步  1:定义2:实例化委托(多种写法) 3:调用委托

方式一、基本传统标准的写法,适合于: 委托已有的方法

Handler  handler = new Handler(Fun);

Handler  handler = Fun; //简化的写法 等号右边 表示的是委托对象

方式三:匿名方法,适合于:

功能简单少量代码可以完成,且该功能不需要在其它地方复用.

Handler  handler = delegate(int a)    等号右边 表示的是委托对象=匿名方法

{

      for (int i = 0; i < a; i++)

      Console.WriteLine("HAHA");

};

方式四:Lambda 表达式,适合于:

写法一:功能简单少量代码可以完成,且该功能不需要在其它地方复用

写法二:功能代码超简单,一行代码可以完成

Lambda 表达式语法

委托类型 委托对象名=Lambda 表达式;

             写法 (参数)=>{语句}    => goto

                    (参数1,参数2)=> 一行代码return不能写!

         简化写法二 一个参数=>一行代码return不能写!

 

Handler  handler = (p) => Console.WriteLine(p + "HAHA");

                等号右边 表示的是委托对象=Lambda 表达式=匿名方法

namespace DemoDelegate
{
    //
    class EX3
    {
        static void Main33()
        { 
              
            //2> 4种写法
            //Handler handlerObj = new Handler(Fun);//111
            //Handler handlerObj = Fun;//222
            //Handler handlerObj = delegate(Person p) { ///333
            //    return p.Age;
            //};
            Handler handlerObj =p=>p.Age; //444
            //3>
            Person person=new Person(){
             Id=1, Name="aa", Age=20
            };
            int re = handlerObj(person);

        }
        //static int Fun(Person p)
        //{
        //    return p.Age;
        //}
    }
    //定义端 1>
    public delegate int Handler(Person p); //从一个对象中选一个属性的值 Person id或age
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

}

Lambda 表达式进阶用法↓

namespace DemoDelegate444
{
    //
    class EX4
    {
        static void Main()
        { 
           //2>
            Handler handlerObj = (list, id) =>
            {
                Person person = null;
                foreach (var p in list)
                {
                    if (p.Id == id)
                    {
                        person = p;
                        break;
                    }
                }
                return person;
            
            }; 
            
            //3>  
            List<Person> arr = new List<Person> 
            { 
                new Person(){Id = 1,Name = "aa",Age = 20},
                new Person(){Id = 2,Name = "bb",Age = 22}
            };
            var re = handlerObj(arr, 2);

        }
       
    }
    //定义端 1>
   public  delegate  Person Handler(List< Person> list,int id);
    //从一个集合中选择编号=id的那个对象
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

}

委托实现方法的异步调用

同步调用方法:排队调用,前一个方法执行时,后一个方法等待它的结束后才能启动

异步调用方法:不排队调用,前一个方法如果异步调用,后一个方法不必等待它的结束就可启动,异步调用的方法是创建了一个新线程来工作的,与后一个方法所在不同的线程,各自独立,互不影响

Framework中的任何方法都可以异步调用。前提是通过委托引用该方法,使用BeginInvoke开启异步调用模式。

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

namespace 异步调用
{
    class Program
    {
        static Handler handlerObj = null;
        static void Main(string[] args)
        {
            //同步调用=一个完,才能另一个 阻塞
            //A obja = new A();
            //obja.F1big();
            //obja.F2();

            //异步调用方式很多:1 委托【封装】2多线程【直接使用】
            //2>实例化委托
            A obja = new A();
            handlerObj = new Handler(obja.F1big);
            //3>开始异步调用
            // AsyncCallback参数 要指定一个方法来取结果!           
            handlerObj.BeginInvoke(new AsyncCallback(FunGetRe), null);

            obja.F2();
            Console.ReadKey();
        }
        //定义一个取 结果的方法
        //IAsyncResult 看做 服务员【监控器】
        static void FunGetRe(IAsyncResult ar)
        {
            bool re = ar.IsCompleted;
            // 4>结束异步调用【如果有返回值 可以取返回值】
            if (re)            
            {
                handlerObj.EndInvoke(ar);
                Console.WriteLine("IsCompleted");
            }
        }
    }
    class A
    {
        public void F1big()
        {
            System.Threading.Thread.Sleep(3000);//3001,4000
            Console.WriteLine("1111111111");
        }
        public string F2big(int a)
        {
            System.Threading.Thread.Sleep(3000);//3001,4000
            Console.WriteLine("big big");
            return a.ToString();
        }
        public void F2()
        {
            Console.WriteLine("222222");
        }
    }
    //1>定义相应的委托
    delegate  void Handler ();
}

猜你喜欢

转载自blog.csdn.net/huanyu0127/article/details/107152487
今日推荐