每日一句:同是风华正茂,怎能甘拜下风
目录
可以用【Action委托】和【Func委托】来声明委托(两个内置的委托类型)
什么是委托?
一种类,引用类型,可以存储/封装一个,或多个方法的引用
(委托有参数列表和返回值类型),
当实例化委托后,即创建委托的实例,
这个委托类型的实例,可以和任何其他方法相关联起来,即可以存储这些方法的引用只要类型兼容(类型兼容:任何方法的签名和返回值与委托类型的签名和返回值保持一致),
可以通过委托类型的实例(对象)间接调用这些方法。
【现实】世界(具体)
有一件事情,不亲自去做,而是交给别人替我去做那些本来该我做的事情。
【程序】世界(抽象)
有一个或多个方法,这些方法不需要亲自的直接调佣,而是赋值给委托类型的变量,委托类型的变量将会存储这几个方法,
委托会指向这几个方法,由委托类型的变量来【间接的调用】这些方法
委托为何重要?
- 面试
- 事件的基础是委托,Lambda表达式基础也是委托,Lambda是LINQ的基础
自定义委托的声明
public delegate void MyDelegate();
void 目标方法的返回值类型(目标方法;委托可以指向的方法)
(类似于C语言的声明一个函数指针,C#由C++发展而来,通过委托,保留了与函数指针相对应的部分内容)
public delegate void MyDelegate();//声明委托类型
MyDelegate myDelegate;//声明委托类型的变量间接的调用方法
void OnEnable()
{//单播委托
myDelegate=new MyDelegate(Teleport);//创建一个委托类型的实例,将方法赋值到委托类型
的变量中
委托myDelegate指向的目标方法是一个[参数列表为空][返回值为void类型]的方法【目标兼容】
//myDelegate=Teleport;(简化)更加清楚表达出将Teleport方法赋值给委托类型的变量myDelegate中
//myDelegate=new MyDelegate(ChangeColor);
//多播委托
myDelegate+=ChangeColor;
//myDelegate=ChangeColor;//会覆盖掉之前的方法
myDelegate+=Log;
}
void Update()
{ myDelegate();
//myDelegate.Invoke();
}
void Teleport()
{}
void ChangeColor()
{}
委托引用一个实例方法(隶属于一个对象,这个对象必须存在内存中)
可以用【Action委托】和【Func委托】来声明委托(两个内置的委托类型)
Action action01;
Func<string,string> func01;//目标方法的参数列表类型,返回值类型
Func<double,double,double>(Add);//Add(double(double,double))
private void OnEnable()
{ action01=new Action(Teleport);
func01=new Func<string>(Log);
func02=new Func<double,double,double>(Add);
}
void Teleport()
{}
string Log()
{}
double Add(double _num1,double _num2)
{}
void Start()
{ anction01();
func01();
func02(2.2f,3.8f);//方法的参数
}
使用委托【间接调用】方法比【直接调用】好在哪里?
委托可以封装任意一个与之类型兼容的方法
Action委托:一定指向一个【无返回值】的方法,至于参数列表,可有可无,最多16个
Funct委托:一定指向一个【有返回值】的方法,至于参数列表,可有可无,最多16个
委托的缺点:
难精通+易使用+功能强大,一旦别滥用则后果非常严重
- 一种方法级别的紧耦合,实现工作慎之
- 可读性下降,debug难度增加
- 把委托回调,异步调用和多线程纠缠在一起,让代码难以阅读
- 使用不当,可能造成内存泄漏和程序性能下降和维护
模板方法
有一处不确定的,其余代码都是确定好的,这个不确定的部分,就靠传进来的委托类型的参数所包含的这个方法来填补,所以一定是有返回值Func<T>委托类型的参数方法
回调方法
以回调方法形式使用【委托】根据逻辑,动态选择是否调用
委托是一个引用类型,将委托当作方法的参数,传递到别的方法中,间接的去调用委托所封装的方法,从而形成动态调用方法的代码结果
//以上内容听B站宝藏Up主—BeaverJoe的课,做的学习笔记