经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C# 委托 事件
来源:cnblogs  作者:胖胖滴加菲猫  时间:2018/12/21 10:53:05  对本文有异议

一:什么叫委托

通过反射发现,委托其实是一个类,继承自System.MulticastDelegate,但是System.MulticastDelegate这个类是特殊类,不能被继承

 

二:委托的声明 

  1. public delegate void NoReturnNoParaOutClass();
  2. public class MyDelete
  3. {
  4. public delegate void NoReturnNoPara<T>(T t);
  5. public delegate void NoReturnNoPara();
  6. public delegate void NoReturnWithPara(int x, int y);
  7. public delegate int WithReturnNoPara();
  8. public delegate string WithReturnWithPara(out int x, ref int y);
  9. }

委托可以声明在类外面,可以声明再类里面

 

三:委托的实例和调用 

  1. private int GetSomething()
  2. {
  3. return 1;
  4. }
  5. private int GetSomething2()
  6. {
  7. return 2;
  8. }
  9. private int GetSomething3()
  10. {
  11. return 3;
  12. }
  13. private void DoNothing()
  14. {
  15. Console.WriteLine("This is DoNothing");
  16. }
  17. private static void DoNothingStatic()
  18. {
  19. Console.WriteLine("This is DoNothingStatic");
  20. }
  21. public string ParaReturn(out int x, ref int y)
  22. {
  23. throw new Exception();
  24. }
View Code

 

  1. //多种途径实例化,要求传递一个参数类型,返回值都跟委托一致的方法
  2. {
  3. WithReturnWithPara method = new WithReturnWithPara(ParaReturn);
  4. int x = 0;
  5. int y = 0;
  6. var dd = method.Invoke(out x, ref y);
  7. }
  8. //begininvoke
  9. {
  10. WithReturnNoPara method = new WithReturnNoPara(this.GetSomething);
  11. int iResult = method.Invoke();
  12. iResult = method();
  13. var result = method.BeginInvoke(null, null);//异步调用
  14. method.EndInvoke(result);
  15. }
  16. {
  17. NoReturnNoPara method = new NoReturnNoPara(this.DoNothing);
  18. //委托实力的调用,参数和委托约束的一致
  19. method.Invoke(); //1
  20. //method(); //2
  21. //method.BeginInvoke(null, null); //3
  22. //this.DoNothing(); //1,2,3都等同于this.DoNothing
  23. }
  24. {
  25. NoReturnNoPara method = new NoReturnNoPara(DoNothingStatic);
  26. }
  27. {
  28. NoReturnNoPara method = new NoReturnNoPara(Student.StudyAdvanced);
  29. }
  30. {
  31. NoReturnNoPara method = new NoReturnNoPara(new Student().Study);
  32. }

 

四:为什么要使用委托

有时候我们声明一个方法,直接调用蛮好的,为啥还要使用委托,然后还要先声明,再实例化,再inovke调用呢?

下面我们举个例子,比如一个人问好这件事情,不同人问候方式不一样,我们会先定义一个类型,如枚举

  1. public enum PeopleType
  2. {
  3. Chinese,
  4. America,
  5. Japanese
  6. }

然后通过不同的类型来判断问候方式不同,如下

  1. /// 为不同的人,进行不同的问候
  2. /// 传递变量--判断一下----执行对应的逻辑
  3. /// </summary>
  4. /// <param name="name"></param>
  5. /// <param name="peopleType"></param>
  6. public void SayHi(string name, PeopleType peopleType)
  7. {
  8. switch (peopleType)
  9. {
  10. case PeopleType.Chinese:
  11. Console.WriteLine($"{name}晚上好");
  12. break;
  13. case PeopleType.America:
  14. Console.WriteLine($"{name},good evening");
  15. break;
  16. case PeopleType.Japanese:
  17. Console.WriteLine($"{name},&&%*^^***@@@&&&&");
  18. break;
  19. default:
  20. throw new Exception("wrong peopleType"); //遇到异常报错
  21. }
  22. }

这样做的好处是:以后如果增加公共逻辑等比较容易,但是如果类型比较多,这个方法会变成无限制改动,导致方法难以维护,于是很多人想着增加分支,就增加方法--不影响别的方法的思路来改善

  1. public void SayHiChinese(string name)
  2. {
  3. Console.WriteLine($"{name}晚上好");
  4. }
  5. public void SayHiJapanese(string name)
  6. {
  7. Console.WriteLine($"{name},&&%*^^***@@@&&&&");
  8. }
  9. public void SayHiAmerican(string name)
  10. {
  11. Console.WriteLine($"{name},good evening");
  12. }

然后上层判断调用

这样做的好处是:修改某个方法--不影响别的方法 ,但是缺点却是:增加公共逻辑---多个方法就有很多重复代码

那么我们想:既增加逻辑方便,又维护简单,鱼肉熊掌,如何兼得呢?

我们可以把相应的逻辑做为参数传进来,这样就解决了我们的问题

具体我们可以按照以下来做:

  1. public void SayHiPerfact(string name, SayHiDeletegate method)
  2. {
  3. Console.WriteLine("增加开始日志");
  4. method.Invoke(name);
  5. Console.WriteLine("增加结束日志");
  6. }
  7. public delegate void SayHiDeletegate(string name);

然后调用的时候如下:

  1. SayHiDeletegate method = new SayHiDeletegate(SayHiChinese);

这样就做到了

1:逻辑解耦,方便维护 

2:代码重构,去掉重复

其实这也是我们选择使用委托的两大优点

注意:以上我们纯粹为了定义委托而定义委托,其实框架已经我们帮我们定义了Action 和Func这两个委托,Action是没有返回值,Func是有返回值的,这两个委托类已经足够我们使用了,所以有时候我们使用的时候,没有必要自己再去定义,而直接使用即可

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号