一 . delegate (自定义委托)

  事件的监听与注册(unity版本)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace colorzore
{
    public class EventTest01 : MonoBehaviour
    {
        public Button button;
        public Text text1;
        public Text text2;

        private int num = 0;

        private void Awake()
        {
            button.onClick.AddListener(delegate
            {
                //执行唤醒方法
                if (num%2 == 0)
                {
                    //执行text1更改
                    EventCenter.Broadcast(EventType.changeText1);
                }
                else
                {
                    //执行Text2事件
                    EventCenter.Broadcast(EventType.changeText2,num);
                }

                num++;
            });
            
            //添加text1的注册事件
            EventCenter.AddListener(EventType.changeText1, delegate
            {
                text1.text = "changText1" + num;
            });
            
            EventCenter.AddListener(EventType.changeText2, (int value) =>
            {
                text2.text = "changeText2 value:" + num;
            });
        }
        
    }
    

    public enum EventType
    {
        changeText1,
        changeText2,
    }

    public class EventCenter
    {
        private static Dictionary<EventType,Delegate> m_EventTable = new Dictionary<EventType, Delegate>();

        private static void OnListernerRemoving(EventType eventType, Delegate callBack)
        {
            if (m_EventTable.ContainsKey(eventType))
            {
                Delegate d = m_EventTable[eventType];
                if (d == null)
                {
                    throw  new Exception(string.Format("移除监听错误:事件{0}没有对应的委托",eventType));
                }
                else if(d.GetType() != callBack.GetType())
                {
                    throw new Exception(string.Format("移除监听错误:尝试为事件{0}移除不同类型的委托{1}",d.GetType(),eventType));
                }
            }
            else
            {
                throw new Exception(string.Format("移除监听错误:没有事件码{0}",eventType));
            }
        }
        
        
        private static void OnListenerRemoved(EventType eventType)
        {
            if (m_EventTable[eventType] == null)
            {
                m_EventTable.Remove(eventType);
            }
        }
        
        //no parameters,添加监听
        public static void AddListener(EventType eventType, CallBack callBack)
        {
            if (!m_EventTable.ContainsKey(eventType))
            {
                m_EventTable.Add(eventType,null);
            }
            Delegate d = m_EventTable[eventType];
            if (d != null && d.GetType()!= callBack.GetType())
            {
                throw  new Exception(string.Format("尝试为事件{0}添加不同类型的委托," +
                                                   "当前事件所对应的委托是{1},要添加的委托类型为{2}",d.GetType(),eventType,callBack));
            }
            m_EventTable[eventType] = (CallBack) m_EventTable[eventType] + callBack;
            
        }
        
        //single parameters
        public static void AddListener<T>(EventType eventType, CallBack<T> callBack)
        {
            //检查是否存在该类型
            if (!m_EventTable.ContainsKey(eventType))
            {
                m_EventTable.Add(eventType, null);
            }

            Delegate d = m_EventTable[eventType];
            if (d != null && d.GetType() != callBack.GetType())
            {
                throw new Exception(String.Format("尝试为事件{0}添加不同类型的委托," +
                                                  "当前事件所对应的委托是{1}," +
                                                  "要添加的委托类型为{2}",d.GetType(),eventType,callBack));
            }

            m_EventTable[eventType] = (CallBack<T>) m_EventTable[eventType] + callBack;
        }
        
        
        //移除监听
        public static void RemoveListener(EventType eventType, CallBack callBack)
        {
            OnListernerRemoving(eventType,callBack);
            OnListenerRemoved(eventType);
            m_EventTable[eventType] = (CallBack) m_EventTable[eventType] - callBack;
        }
        
        //Single parameters
        public static void RemoveListener<T>(EventType eventType, CallBack<T> callBack)
        {
            OnListernerRemoving(eventType,callBack);
            OnListenerRemoved(eventType);
            m_EventTable[eventType] = (CallBack<T>) m_EventTable[eventType] - callBack;
        }
        

        //播送事件
        //no parameters
        public static void Broadcast(EventType eventType)
        {
            Delegate d;
            if (m_EventTable.TryGetValue(eventType, out d))
            {
                CallBack callBack = d as CallBack;
                if (callBack != null)
                {
                    callBack();
                }
                else
                {
                    throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型",eventType));
                }
            }
        }

        public static void Broadcast<T>(EventType eventType, T arg)
        {
            Delegate d;
            if (m_EventTable.TryGetValue(eventType, out d))
            {
                CallBack<T> callBack = d as CallBack<T>;
                if (callBack != null)
                {
                    callBack(arg);
                }
                else
                {
                    throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型",eventType));
                }
            }
        }
    }
    
    //设置委托
    public delegate void CallBack();
    public delegate void CallBack<T>(T arg);
}

 

  

 

二.系统内置(预定义)的委托类型

  1. Action委托
    1. 不带返回值
    2. 可以指向一个没有返回值,没有参数的方法
    3.  1 class Program
       2     {
       3         static void PrintString()
       4         {
       5             Console.WriteLine("hello world.");
       6         }
       7         static void PrintInt(int i)
       8         {
       9             Console.WriteLine(i);
      10         }
      11         static void PrintString(string str)
      12         {
      13             Console.WriteLine(str);
      14         }
      15 
      16         static void PrintDoubleInt(int x, int y)
      17         {
      18             Console.WriteLine(x + " " + y);
      19         }
      20         /// <summary>
      21         /// Action委托不带返回值
      22         /// </summary>
      23         /// <param name="args"></param>
      24         static void Main(string[] args)
      25         {
      26             //Action a = PrintString; //action是系统内置(预定义)的一个委托类型,他可以指向一个没有返回值,没有参数的方法
      27 
      28             //Action<int> a =PrintInt;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个int参数的方法
      29 
      30             //Action<string> a = PrintString;//定义了以哦个委托类型,这个类型可以指向一个没有返回值,有string参数的方法,在这里系统会自动寻找匹配的方法
      31 
      32             Action<int, int> a = PrintDoubleInt;
      33             a(24, 45);
      34 
      35             Console.ReadKey();
      36             //action 可以后面通过泛型去指定action指向的方法的多个参数的类型,参数的类型跟后面声明的委托类型是对应着的
      37         }
      38     }

       

    4. 可以指向一个没有返回值,有一个或者多个参数的方法(最多参数16个)
  2. Predicate委托
    1. Precicate 是返回bool 型的泛型委托,只能接收一个传入参数
  3. Func委托
    1. 必含一个返回值
    2. 最后一个类型表示返回值类型,前面的表示参数类型
      •  1 using System;
         2 using System.Collections.Generic;
         3 using System.Linq;
         4 using System.Text;
         5 
         6 namespace _00_Func委托
         7 {
         8     /// <summary>
         9     /// Func 必含一个返回值
        10     /// 最后一个类型表示返回值类型,前面的表示参数类型
        11     /// </summary>
        12     class Program
        13     {
        14         static int Test1()
        15         {
        16             return 1;
        17         }
        18         static int Test2(string str)
        19         {
        20             Console.WriteLine(str);
        21             return 100;
        22         }
        23         static int Test3(int i, int j)
        24         {
        25             return i + j;
        26         }
        27         static void Main(string[] args)
        28         {
        29             //Func<int> a = Test1;//func中的泛型类型指定的是 方法发返回值类型
        30             //Console.WriteLine(a());
        31 
        32             //Func<string, int> a = Test2; //Func后面可以跟很多类型,最后一个类型是返回值类型,前面的类型是参数类型,参数类型必须跟指向的方法的参数类型按照顺序对应
        33 
        34             Func<int, int, int> a = Test3;//func后面必须指定一个返回值类型,参数可以有0-16个,先写参数类型,最后一个是返回值类型
        35             int aa = a(1, 5);
        36 
        37             //Console.WriteLine(a("读大"));
        38             Console.ReadKey();
        39         }
        40     }
posted on 2019-12-23 02:44  冷榷  阅读(181)  评论(0编辑  收藏  举报