委托学习
第一节:
1.委托的声明、实例化和调用(三部曲)
//1定义(定义在类里面或者外面(不能再方法里面))
/*
* public delegate void MyDelegate1();//无参数
* public delegate void MyDelegate2(int x, int y);//有参数
*/
//2实例化
{
MyDelegate2 myDelegate2 = new MyDelegate2(Plus);//传方法名称 要求:方法签名一致
//MyDelegate2 myDelegate2_1 = Plus;//第二种实例化
//3调用
myDelegate2.Invoke(1, 2);
myDelegate2(1, 2);//两者完全一致
myDelegate2.BeginInvoke(3, 4, null, null);//异步调用 另起线程完成
2.委托的意义:解耦
实例:打招呼 (中文/英文):
传统方法:
定义一个方法,一个枚举。
方法用于实现代码逻辑,使用if判断值,从而执行相应的行为,方法参数有两个,1.打招呼的人名称,2.打招呼的类型(这里指中文或者英文)。
枚举用来判断打招呼的类型
使用委托解耦方法:
定义三个方法。
在本次实例中是指:一个中文打招呼的方法和一个英文打招呼的方法;还有一个用于调用委托的方法(方法参数有两个:第一个是打招呼的名称,第二个参数是一个委托类型(注:在改方法实例化的时候就决定了执行了什么行为,中文或者英文))。
扩展:
需求:添加一个日语打招呼的方式。
传统方法实现:
添加枚举类型,然后修改实现方法的逻辑,判断类型为日语执行对应的操作
委托解耦方法实现:
添加一个日语行为的方法,在使用的时候决定是否使用日语打招呼。
价值:
传统方法需要修改实现的方法(耦合太多(职责太多))
委托解耦方法添加日语方法,调用时改为日语委托(对扩展开放,对修改封闭)(单一职责的体现)
第二节:
1.lambda表达式
2.系统自带的各种委托
3.Linq扩展
//1.lambda表达式(本质就是一个方法)
{
//1.1 使用匿名方法实现
MyDelegate2 method1 = new MyDelegate2(
delegate (int x, int y)
{
Console.WriteLine();
});
//1.2 使用=>代替delegate,左边是参数,右边是方法体
MyDelegate2 method2 = new MyDelegate2((int x, int y) =>
{
Console.WriteLine();
});
//1.3委托的实例化的约束,所以可以去掉参数类型
MyDelegate2 method3 = new MyDelegate2((x, y) =>
{
Console.WriteLine();
});
//1.4 new关键字可以省略
MyDelegate2 method4 = (x, y) => { Console.WriteLine(); };
//1.5 去掉{},条件是:方法体只有一行;带返回值的话省略return
MyDelegate2 method5 = (x, y) => Console.WriteLine();
/*
* 注:
* 一个参数可以去掉小括号
*/
}
第三节:
* 1.多播委托
* 2.观察者模式和事件
//1.多播委托(把多个方法注册在同一个委托里面)
MyDelegate2 method = new MyDelegate2(Plus);
method += Plus;//将委托多加一个执行方法
method -= Plus;//将委托减少一个执行方法
//在调用时一次性调用
/*
* 注:
* method.GetInvocationList()获取委托注册的所有方法
*/
//2.观察者模式和事件(触发时不知道后面会发生什么)
//A执行的时候引发 B C D
//使用多播委托实现
/*
* 思路:
* 在A类定义一个委托
* 在调用A操作是添加BCD操作
* 然后在执行A是执行委托(添加判断不为null)
*
* 好处:
* 解耦,不在A类添加过多的逻辑
* 维护方便,对修改封闭,对扩展丰富
*/
//2.2 事件
//委托是一种类型,事件是委托类型的实例
//public event delegate void MyDelegate2(int x, int y); 声明事件
/*
* 与委托的区别:(权限的控制,防止外面直接赋值null,导致注册失败,即无执行方法)
* 不能初始化(只能采取+= or -=)
* 不能被外部调用
*/
实例:
调用端代码:
ClsA a = new ClsA();
a.APrint += ClsB.B;
ClsA类代码:
public delegate void MyDelegate2();
class ClsA
{
public event MyDelegate2 APrint;
public void A()
{
Console.WriteLine("触发A");
APrint?.Invoke();
}
}
ClsB类代码:
class ClsB
{
public static void B()
{
Console.WriteLine("触发B");
}
}