做网站购买域名之后,最新军事战况,网站建设合同封皮,沙漠风网站开发怎样一. 委托的发展历史和基本用法 说起委托#xff0c;每个人可能都会对他有不同的理解#xff0c;结合实战中委托的使用#xff0c;我对其理解是#xff1a;委托和类一样#xff0c;是用户的一个自定义类型#xff0c;委托可以有参数、有返回值#xff0c;委托的关键字是d…一. 委托的发展历史和基本用法 说起委托每个人可能都会对他有不同的理解结合实战中委托的使用我对其理解是委托和类一样是用户的一个自定义类型委托可以有参数、有返回值委托的关键字是delegate委托是方法的抽象有了委托的存在使得方法可以作为参数传递给另一个方法同时调用委托的时候委托所包含的所有方法都会被实现。 委托的写法由繁琐→简洁经历了好多过程大致概括为new实例化传递方法→直接等于方法名→new实例化中传递匿名方法→省略匿名方法关键字→可以去掉大括号和分号 等等。 代码如下 1 public class MyDelegate2 {3 //1. 委托的声明4 public delegate void NoReturnNoPara();5 public delegate int WithReturnNoPara();6 public delegate void NoReturnWithPara(int id, string name);7 public delegate MyDelegate WithReturnWithPara(DateTime time);8 9
10 //2. 委托的使用(在show方法中调用)
11 public void Show()
12 {
13 //以“有参无返回值委托”为例,介绍委托的各种用法
14 //2.1 用法一
15 {
16 NoReturnWithPara methord new NoReturnWithPara(this.Test1);
17 methord.Invoke(1, 唐马儒1);
18 }
19 //2.2 用法二
20 {
21 NoReturnWithPara methord this.Test1;
22 methord.Invoke(2, 唐马儒2);
23 }
24 //2.3 用法三 DotNet 2.0 时代
25 {
26 NoReturnWithPara methord new NoReturnWithPara
27 (
28 delegate(int id, string name)
29 {
30 Console.WriteLine({0} {1}, id, name);
31 }
32 );
33 methord.Invoke(3, 唐马儒3);
34 }
35 //2.4 用法四 DotNet 3.0 时代
36 {
37 NoReturnWithPara methord new NoReturnWithPara
38 (
39 (int id, string name)
40 {
41 Console.WriteLine({0} {1}, id, name);
42 }
43 );
44 methord.Invoke(4, 唐马儒4);
45 }
46 //2.5 用法五 委托约束
47 {
48 NoReturnWithPara methord new NoReturnWithPara
49 (
50 (id,name)
51 {
52 Console.WriteLine({0} {1}, id, name);
53 }
54 );
55 methord.Invoke(5, 唐马儒5);
56 }
57 //2.6 用法六 如果方法体只有一行可以去掉大括号和分号
58 {
59 NoReturnWithPara methord new NoReturnWithPara((id, name) Console.WriteLine({0} {1}, id, name));
60 methord.Invoke(6, 唐马儒6);
61 }
62 //2.7 用法七
63 {
64 NoReturnWithPara methord (id, name) Console.WriteLine({0} {1}, id, name);
65 methord.Invoke(7, 唐马儒7);
66 methord(7, 唐马儒7);
67 }
68 //2.8 用法八
69 {
70 //Funcint, bool methord (x)
71 // {
72 // return x 6;
73 // };
74 //等价于(原理当只有一个参数的时候可以省略参数的小括号当方法体只有一行的时候可以省略大括号和分号即lambda形式)
75 Funcint, bool methord x x 6;
76 Console.WriteLine(methord.Invoke(8));
77 }
78
79 }
80 private void Test1(int id, string name)
81 {
82 Console.WriteLine({0} {1}, id, name);
83 }
84
85 private void Test2()
86 {
87 Console.WriteLine(DoNothing);
88 }
89
90 private void Test3()
91 {
92 Console.WriteLine(DoNothing);
93 }
94 } 二. 解耦、插件式编程 1. 背景有一个CarFactory工厂类可以建造自然吸气发动机、涡轮增压发动机、电动发动机至于要建造哪个发动机有多种处理方案。 方案(一)通过传递不同的参数来建造不同的发动机 原理传递一个参数,根据参数类型来执行不同的逻辑 缺点如果增加新的发动机类型,需要修改BuildEngine方法中的内部逻辑,不符合开闭原则 代码如下 1 /// summary2 /// 这里建一个Car工厂,用来建造三种不同类型的发动机3 /// /summary4 public class CarFactory5 {6 /// summary7 /// 方案一通过传递不同的参数来建造不同的发动机8 /// 原理传递一个参数,根据参数类型来执行不同的逻辑9 /// 缺点如果增加新的发动机类型,需要修改BuildEngine方法中的内部逻辑,不符合开闭原则
10 /// /summary
11 /// param nametype参数类型/param
12 public static void BuildEngine(EngineType type)
13 {
14 if (type EngineType.NaturalInspiration)
15 {
16 Console.WriteLine(建造自然吸气发动机);
17 }
18 else if (type EngineType.Turbo)
19 {
20 Console.WriteLine(建造涡轮增压发动机);
21 }
22 else if (type EngineType.Electric)
23 {
24 Console.WriteLine(建造电动发动机);
25 }
26 }
27
28 /// summary
29 /// 发动机类型的枚举类
30 /// /summary
31 public enum EngineType
32 {
33 NaturalInspiration 0, //自然吸气
34 Turbo 1, //涡轮增压
35 Electric 2 //电动
36 }
37 } 调用
1 //1.传统的方式,通过参数类型来区分
2 Console.WriteLine(--------------------------1.传统的方式,通过参数类型来区分------------------------------------);
3 CarFactory.BuildEngine(EngineType.NaturalInspiration);
4 CarFactory.BuildEngine(EngineType.Turbo);
5 CarFactory.BuildEngine(EngineType.Electric); 结果 方案(二)通过传递委托来建造不同的发动机 原理传递一个逻辑给我,我去执行 优点如果增加新的发动机,只需要单独新增对应建造发动机的方法即可,不需要改变BuildEngine2的内部逻辑,符合开闭原则 代码如下 1 public class CarFactory2 {3 /// summary4 /// 方案二通过传递委托来建造不同的发动机5 /// 原理传递一个逻辑给我,我去执行6 /// 优点如果增加新的发动机,只需要单独新增对应建造发动机的方法即可,不需要改变BuildEngine2的内部逻辑,符合开闭原则7 /// /summary8 public static void BuildEngine2(BuildEngineDel be)9 {
10 be.Invoke();
11 }
12 //声明一个无参数的委托
13 public delegate void BuildEngineDel();
14 //下面三个是建造不同发动机的方法
15 public static void BuildNatural()
16 {
17 Console.WriteLine(建造自然吸气发动机);
18 }
19 public static void BuildTurbo()
20 {
21 Console.WriteLine(建造涡轮增压发动机);
22 }
23 public static void BulidElectric()
24 {
25 Console.WriteLine(建造电动发动机);
26 }
27
28 }
29 } 调用 1 //2.将委托当做参数,进行解耦,实现插件式编程(案例一)
2 Console.WriteLine(--------------------------2.将委托当做参数,进行解耦,实现插件式编程(案例一)------------------------------------);
3 //将方法赋给委托,将委托当做参数传递给新方法
4 CarFactory.BuildEngineDel be1 CarFactory.BuildNatural;
5 CarFactory.BuildEngine2(be1);
6 CarFactory.BuildEngineDel be2 CarFactory.BuildTurbo;
7 CarFactory.BuildEngine2(be2);
8 CarFactory.BuildEngineDel be3 CarFactory.BulidElectric;
9 CarFactory.BuildEngine2(be3); 结果 2. 背景:现在有一个类该类要实现对一个int类型的数组中的每个数进行加倍、平方、立方,并输出 传统解决方案一在该类中声明多个方法分别是加倍、平方、立方的方法 传统解决方案二在该类中声明一个万能方法通过传递不同的参数类型来区分是执行加倍还是平方或者立方操作 方案三声明一个万能方法传递一个委托进来相当于传递了一个业务逻辑进行在该方法里只需要执行即可 代码如下 1 public class Calculator2 {3 //解决方案三声明一个万能方法传递一个委托进来相当于传递了一个业务逻辑进行在该方法里只需要执行即可4 /// summary5 /// 万能方法6 /// /summary7 /// param namearrsint类型的数组 /param8 /// param namemydel系统自带的委托也可以自定义委托int,int代表参数和返回值均为int类型/param9 public static void MySpecMethord(int[] arrs, Funcint,int mydel)
10 {
11 for (int i 0; i arrs.Length; i)
12 {
13 arrs[i] mydel(arrs[i]);
14 //arrs[i] mydel.Invoke(arrs[i]); //等价于上面那句
15 Console.WriteLine(arrs[i]);
16 }
17 }
18
19 } 三种调用形式声明Func委托把方法赋值给它、直接把方法名传递进去、传递lambda方法。 1 Console.WriteLine(--------------------------3.将委托当做参数,进行解耦,实现插件式编程(案例二)------------------------------------);2 int[] arr { 1, 2, 3, 4, 5 };3 //调用形式一4 Console.WriteLine(--------------------------调用形式一------------------------------------);5 Funcint, int mydel t1;6 Calculator.MySpecMethord(arr, mydel);7 //调用形式二8 Console.WriteLine(--------------------------调用形式二------------------------------------);9 Calculator.MySpecMethord(arr, t2);
10 //调用形式三
11 Console.WriteLine(--------------------------调用形式三------------------------------------);
12 Calculator.MySpecMethord(arr, x x * 2);
13 /// summary
14 /// 加倍方法
15 /// /summary
16 /// param namex/param
17 /// returns/returns
18 public static int t1(int x)
19 {
20 return x * 2;
21 }
22 /// summary
23 /// 乘方方法
24 /// /summary
25 /// param namex/param
26 /// returns/returns
27 public static int t2(int x)
28 {
29 return x * x;
30 }
31 /// summary
32 /// 立方方法
33 /// /summary
34 /// param namex/param
35 /// returns/returns
36 public static int t3(int x)
37 {
38 return x * x * x;
39 } 结果 三. 多播委托 1. 含义所有的委托的实例都有多播的功能,自定义委托和内置委托都有可以通过和-给委托增加和删掉不同的方法。 下面的代码中分别介绍四个不同类别的方法赋值给普通委托和多播委托的形式。 1 public class myMultiDelegate2 {3 //自定义一个没有参数没有返回值的委托4 public delegate void NoReturnNoPara();5 6 /// summary7 /// 测试委托常规用法8 /// /summary9 public void show1()
10 {
11 Student student new Student();
12 //委托的普通用法,分别调用当前类的实例方法、当前类的静态方法、其他类的实例方法、其他类的静态方法
13 //声明4个委托
14 NoReturnNoPara n1 this.DoNothing; //调用当前类的实例方法
15 NoReturnNoPara n2 myMultiDelegate.DoNothingStatic; //调用当前类的静态方法
16 NoReturnNoPara n3 student.Study;
17 NoReturnNoPara n4 Student.StudyAdvanced;
18
19 //执行
20 n1.Invoke();
21 n2.Invoke();
22 n3.Invoke();
23 n4.Invoke();
24 }
25 /// summary
26 /// 测试多播委托的用法
27 /// /summary
28 public void show2()
29 {
30 //所有的委托的实例都有多播的功能,自定义委托和内置委托都有
31 NoReturnNoPara n1 this.DoNothing;
32 //就是把多个方法按顺序排成列表invoke时按顺序执行
33 n1 myMultiDelegate.DoNothingStatic;
34 n1 Student.StudyAdvanced;
35 n1 this.DoNothing;
36 n1 this.DoNothing;
37 n1 this.DoNothing;
38 n1 this.DoNothing;
39 //-就是从这个实例上从后往前挨个匹配找到第一个完全吻合的移除掉且只移除一个找不到不异常
40 //注意对于委托 和 - 对null是不会报错的
41 n1 - this.DoNothing;
42 n1.Invoke();
43 }
44
45
46 #region 两个供委托调用的测试方法
47 private void DoNothing()
48 {
49 Console.WriteLine(当前类中的实例方法);
50 }
51 private static void DoNothingStatic()
52 {
53 Console.WriteLine(当前类中的静态方法);
54 }
55 #endregion
56 } 2. 多播委托的实际使用场景。 实际注册业务场景先查询账号是否存在(如果不存在)→向表1中插入信息→向表2中插入信息。。。。随着业务新需求的变更,注册时需要向表3中插入数据, 过了一段时间需求又变了不需要向表2中添加数据了。 下述代码是一个注册流程的类。 1 public class RegisterUtils2 {3 //传统的解决方案,在一个方法里书写各种业务。4 //缺点后期需求变更了,当需要插入更多数据的时候,只能修改该方法内部逻辑,不符合开闭原则5 6 7 //下面介绍利用多播委托进行解耦插件式开发8 public delegate void myRegisterDelegate(string userName, string userPwd);9
10 public static void myRegister(myRegisterDelegate mrd, string userName, string userPwd)
11 {
12 //对密码进行Md5加密后在进行后续操作
13 string md5userPwd userPwd MD5; //模拟Md5
14 mrd.Invoke(userName, md5userPwd);
15 }
16 /// summary
17 /// 查询方法
18 /// /summary
19 public static void checkIsRegister(string userName, string userPwd)
20 {
21 Console.WriteLine(查询成功);
22 }
23 /// summary
24 /// 向表1中插入数据
25 /// /summary
26 public static void writeTable1(string userName, string userPwd)
27 {
28 Console.WriteLine(向表1中插入数据{0}{1},userName,userPwd);
29 }
30 /// summary
31 /// 向表2中插入数据
32 /// /summary
33 public static void writeTable2(string userName, string userPwd)
34 {
35 Console.WriteLine(向表2中插入数据{0}{1}, userName, userPwd);
36 }
37 /// summary
38 /// 向表3中插入数据
39 /// /summary
40 public static void writeTable3(string userName, string userPwd)
41 {
42 Console.WriteLine(向表3中插入数据{0}{1}, userName, userPwd);
43 }
44 } 调用 1 Console.WriteLine(--------------------------3.多播委托的案例在注册流程中 ------------------------------------);
2 RegisterUtils.myRegisterDelegate mrd RegisterUtils.checkIsRegister;
3 mrd RegisterUtils.writeTable1;
4 mrd RegisterUtils.writeTable2;
5 //需求增加了,向表3中添加数据
6 mrd RegisterUtils.writeTable3;
7 //需求变更了,删除向表2中添加数据
8 mrd - RegisterUtils.writeTable2;
9 RegisterUtils.myRegister(mrd, maru, 123); 结果 补充在下一个章节.Net进阶系列(7)-委托和事件(二)中会继续介绍泛型委托、内置委托、委托的其他性质、委托和事件。