using System.Collections; using System.Collections.Generic; using UnityEngine; //声明委托(delegate),使用delegate关键字声明这个方法时委托方法,不用写方法体 //委托就相当于一个元素是各种方法的“列表”(List) //委托和事件(Event)不同,委托通常要被重用,是一种定义(一种特殊的类),可以定义在类的外部,事件是类的成员,只能定义在类的内部 public delegate string MainDel(string s); public class TestDelegate : MonoBehaviour { //定义事件,本质上就是实例化委托,事件定义在方法外部 //event关键字 委托名 事件名 //event关键字代表这是事件声明,事件是对于委托的再次封装,更加安全 //event关键字后跟上要封装的委托名,委托中已经定义好了方法签名,这里不必再重复定义,委托名后紧跟事件名即可 public event MainDel MainEvent; // Start is called before the first frame update void Start() { //实例化委托,将方法名赋值给委托 //实际上就是实例化的同时为这个“列表”添加了第一个方法 MainDel mainDel = SayHi; //通过+=的方式为这个“列表”添加方法 mainDel += SayHello; //通过-=的方式删减这个“列表”的方法 mainDel -= SayHi; //在委托中可以直接添加匿名函数方法 //在声明时也可以直接声明匿名函数方法,使用delegate关键字代替函数方法名和返回值类型 mainDel += delegate (string s) { print("我是匿名函数" + s); return "我是匿名函数返回值"; }; //匿名方法可以使用lamda表达式简化 //因为委托的参数类型和返回值类型都和其中方法相同,也就是定义委托时已经定义好了参数和返回值 //所以lamda表达式可以将这些定义都简化掉 mainDel += (s) => { print("我是lamda表达式" + s); return "我是lamda表达式返回值"; }; //通过委托实例直接调用这个“列表”中的所有方法,传入相应的参数 //所以委托中的所有方法参数列表必须相同,返回值类型也必须相同 //委托方法按照添加的顺序执行,如果有返回值返回最后执行的函数的返回值 string m = mainDel("我会用委托了"); print(m); //清空委托链(清空委托中的所有方法) mainDel = null; //为事件添加方法,添加方式和委托相同 MainEvent += SayHello; //触发事件 if(MainEvent != null) { MainEvent("事件触发了"); } //清空事件 MainEvent = null; if(MainEvent == null) { print("事件清空了"); } } //供委托调用的方法1 string SayHi(string s) { print("hi" + s); return "我是SayHi函数返回值"; } //供委托调用的方法2 string SayHello(string s) { print("hello" + s); return "我是SayHello函数返回值"; } }