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函数返回值";
}
}