一、委托Delegate

一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本的数据类型(或者没有参数),比如

[c-sharp] view plaincopy
  1. public void HelloWorld()
  2. {
  3. Console.WriteLine("Hello World!");
  4. }
  5. public void HelloWorld(string name)
  6. {
  7. Console.WriteLine("Hello ,{0}!", name);
  8. }

但是有些时候,我们希望把一个方法本身当做参数传递给另一个方法,比如

myObject.callMethod(HelloWorld);

在没有委托之前,这是一件极困难的事情,委托出现以后,这就是一件很容易的事情了,简单点讲:委托就是一种能把方法当做参数来使用的类型--当然这个定义跟官方的解释比起来极不严密,但易于理解

要点:
1.委托是一种类型(跟string,int,double...一样是.net的一种基本类型)
2.委托的定义必须与最终被调用的方法保持签名一致

比如:下面代码中的

delegate void D1(); 与 static void HelloWorld1(),我们抛开前面的类型关键字delegate与static,他们的签名都是void X()
void D2(string myName);与void HelloWorld2(string name); void HelloWorld3(string name);它们的签名格式都是 void X(string Y)

3.委托的好处之一在于可以保持签名格式不变的情况下,动态调用不同的处理逻辑(即不同的方法)

想想系统控件中的Button类,系统并不知道按钮按下去时到底会执行怎么样的逻辑(点击后的处理,每个项目可能都不一样,完全由需求决定),但是我们知道每个Button都有一个Click(object sender, EventArgs e)这样的东东,没错,就是委托(当然封装成了另一种衍生类型event),就是这种设计保证了统一的格式,不管你实际开发中想如何处理点击后的逻辑,只要按这个统一的签名来就行了
完整代码演示:

[c-sharp] view plaincopy
  1. using System;
  2. namespace ActionStudy
  3. {
  4. class Program
  5. {
  6. delegate void D1();
  7. delegate void D2(string myName);
  8. static void Main(string[] args)
  9. {
  10. D1 d1 = new D1(HelloWorld1);
  11. d1();
  12. D2 d2 = new D2(HelloWorld2);
  13. d2("Jimmy");
  14. d2 = new D2(HelloWorld3);
  15. d2("杨俊明");
  16. Console.Read();
  17. }
  18. static void HelloWorld1()
  19. {
  20. Console.WriteLine("Hello World!");
  21. }
  22. static void HelloWorld2(string name)
  23. {
  24. Console.WriteLine("Hello,{0}!", name);
  25. }
  26. static void HelloWorld3(string name)
  27. {
  28. Console.WriteLine("你好,{0}!", name);
  29. }
  30. }
  31. }

二 、匿名方法(.net2.0开始支持)

在“一、委托Delegate”的演示代码中,我们看到委托调用方法前,至少得先定义一个签名相同的方法,然后才能由委托调用(哪怕是只有一行代码的方法),好象有点烦哦,想偷懒,ok,没问题

[c-sharp] view plaincopy
  1. using System;
  2. namespace ActionStudy
  3. {
  4. class Program
  5. {
  6. delegate void D1();
  7. delegate void D2(string myName);
  8. static void Main(string[] args)
  9. {
  10. D1 d1 = delegate
  11. {
  12. Console.WriteLine("Hello World!");
  13. };
  14. d1();
  15. D2 d2 = delegate(string name)
  16. {
  17. Console.WriteLine("Hello,{0}!", name);
  18. };
  19. d2("Jimmy");
  20. d2 = delegate(string name)
  21. {
  22. Console.WriteLine("你好,{0}!", name);
  23. };
  24. d2("杨俊明");
  25. Console.Read();
  26. }
  27. }
  28. }

运行效果完全相同,只是省去了方法的单独定义部分

到了.net 3.0这种偷懒的作风更夸张,看下面的代码(利用了Lambda表达式)

[c-sharp] view plaincopy
  1. using System;
  2. namespace ActionStudy
  3. {
  4. class Program
  5. {
  6. delegate void D1();
  7. delegate void D2(string myName);
  8. static void Main(string[] args)
  9. {
  10. D1 d1 = () => { Console.WriteLine("Hello World!"); };
  11. d1();
  12. D2 d2 = (string name) => { Console.WriteLine("Hello,{0}!", name); };
  13. d2("Jimmy");
  14. d2 = (string name) => { Console.WriteLine("你好,{0}!", name); };
  15. d2("杨俊明");
  16. Console.Read();
  17. }
  18. }
  19. }

运行效果仍然没变,初次接触者可能感觉很怪,其实我也觉得怪,不过很多大牛们都喜欢这样用,所以至少还是要能看得懂,否则别人会说"你 Out了" :)
三、Action

Action的本质就是委托,看它的定义:

[c-sharp] view plaincopy
  1. namespace System
  2. {
  3. // 摘要:
  4. //     Encapsulates a method that takes no parameters and does not return a value.
  5. public delegate void Action();
  6. }
  7. namespace System
  8. {
  9. // 摘要:
  10. //     Encapsulates a method that takes a single parameter and does not return a
  11. //     value.
  12. //
  13. // 参数:
  14. //   obj:
  15. //     The parameter of the method that this delegate encapsulates.
  16. //
  17. // 类型参数:
  18. //   T:
  19. //     The type of the parameter of the method that this delegate encapsulates.
  20. public delegate void Action<T>(T obj);
  21. }

当然,还有Action<T1,T2>乃至Action<T1,T2,T3,T4>参数个数从2到4的类型,不过定义都差不多

简单点讲,Action是参数从0到4,返回类型为void(即没有返回值)的委托

[c-sharp] view plaincopy
  1. using System;  
  2. namespace ActionStudy  
  3. {  
  4.     class Program  
  5.     {  
  6.         static Action A1;  
  7.         static Action<string> A2;  
  8.          
  9.         static void Main(string[] args)  
  10.         {  
  11.             A1 = new Action(HelloWorld1);  
  12.             A1();  
  13.   
  14.             A2 = new Action<string>(HelloWorld2);  
  15.             A2("Jimmy");  
  16.   
  17.             A2 = (string name) => { Console.WriteLine("你好,{0}!", name); };  
  18.             A2("杨俊明");  
  19.   
  20.             A2 = delegate(string name) { Console.WriteLine("我就是委托,{0} 你说对吗?", name); };  
  21.             A2("菩提树下的杨过");            
  22.   
  23.             Console.Read();  
  24.   
  25.         }  
  26.   
  27.         static void HelloWorld1()  
  28.         {  
  29.             Console.WriteLine("Hello World!");  
  30.         }  
  31.   
  32.         static void HelloWorld2(string name)  
  33.         {  
  34.             Console.WriteLine("Hello,{0}!", name);  
  35.         }    
  36.     }  
  37. }  

四、Func

Func其实也是一个"托"儿,呵呵,不过这个委托是有返回值的。看下定义就知道了:

[c-sharp] view plaincopy
  1. namespace System
  2. {
  3. // 摘要:
  4. //     Encapsulates a method that has no parameters and returns a value of the type
  5. //     specified by the TResult parameter.
  6. //
  7. // 类型参数:
  8. //   TResult:
  9. //     The type of the return value of the method that this delegate encapsulates.
  10. //
  11. // 返回结果:
  12. //     The return value of the method that this delegate encapsulates.
  13. public delegate TResult Func<TResult>();
  14. }
  15. namespace System
  16. {
  17. // 摘要:
  18. //     Encapsulates a method that has one parameter and returns a value of the type
  19. //     specified by the TResult parameter.
  20. //
  21. // 参数:
  22. //   arg:
  23. //     The parameter of the method that this delegate encapsulates.
  24. //
  25. // 类型参数:
  26. //   T:
  27. //     The type of the parameter of the method that this delegate encapsulates.
  28. //
  29. //   TResult:
  30. //     The type of the return value of the method that this delegate encapsulates.
  31. //
  32. // 返回结果:
  33. //     The return value of the method that this delegate encapsulates.
  34. public delegate TResult Func<T, TResult>(T arg);
  35. }

同Action类似,Func的参数从1到5个,有5个不同的重载版本
代码:

[c-sharp] view plaincopy
  1. using System;
  2. namespace ActionStudy
  3. {
  4. class Program
  5. {
  6. static Func<string> F;
  7. static Func<DateTime, string> F2;
  8. static void Main(string[] args)
  9. {
  10. F = new Func<string>(HelloWorld1);
  11. Console.WriteLine(F());
  12. F2 = new Func<DateTime, string>(HelloWorld2);
  13. Console.WriteLine(F2(DateTime.Now));
  14. Console.Read();
  15. }
  16. static string HelloWorld1()
  17. {
  18. return "Hello World!";
  19. }
  20. static string HelloWorld2(DateTime time)
  21. {
  22. return string.Format("Hello World,the time is {0}.", time);
  23. }
  24. }
  25. }

五、匿名委托

ok,如果你没有晕的话,再来看一下匿名委托,其实这也是一种偷懒的小伎俩而已
看代码说话:

//F = new Func<string>(HelloWorld1);

其实也可以简写成这样:

F = HelloWorld1;

//F2 = new Func<DateTime, string>(HelloWorld2);

其实也可以简写成这样

F2 = HelloWorld2;

方法直接赋值给委托,这二个类型不同吧???

没错,你会发现编译一样能通过,系统在编译时在背后自动帮我们加上了类似 “= new Func<...>”的东东,所以我们能偷懒一下下,这个就是匿名委托。

如果你细心的话,会发现我们在定义Button的Click处理事件时,通常是这样的:

this.button1.Click += new EventHandler(button1_Click);

但有时候我们也可以写成这样:

this.button1.Click += button1_Click;

这其实就是匿名委托的应用.

六、事件event

其实,这...还是个托儿!

我们来看下按钮Click事件的定义

[c-sharp] view plaincopy
  1. // 摘要:
  2. //     Occurs when the control is clicked.
  3. public event EventHandler Click;

继续刨根问底,查看EventHandler的定义:

[c-sharp] view plaincopy
  1. using System.Runtime.InteropServices;
  2. namespace System
  3. {
  4. // 摘要:
  5. //     Represents the method that will handle an event that has no event data.
  6. //
  7. // 参数:
  8. //   sender:
  9. //     The source of the event.
  10. //
  11. //   e:
  12. //     An System.EventArgs that contains no event data.
  13. [Serializable]
  14. [ComVisible(true)]
  15. public delegate void EventHandler(object sender, EventArgs e);
  16. }

看到了吧,就是委托!

来自菩提树下的杨过http://www.cnblogs.com/yjmyzz/archive/2009/11/23/1608818.html

转载于:https://www.cnblogs.com/zhangchenliang/archive/2012/08/16/2643022.html

Delegate,Action,Func,匿名方法,匿名委托,事件相关推荐

  1. Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)

    Delegate,Action,Func,匿名方法,匿名委托,事件 (转载) 一.委托Delegate 一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本 ...

  2. 匹夫细说C#:委托的简化语法,聊聊匿名方法和闭包

    0x00 前言 通过上一篇博客<匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的>的内容,我们实现了使用委托来构建我们自己的消息系统的过程.但是在日常的开发中,仍然有很多开发者因为 ...

  3. C# 从CIL代码了解委托,匿名方法,Lambda 表达式和闭包本质

    前言 C# 3.0 引入了 Lambda 表达式,程序员们很快就开始习惯并爱上这种简洁并极具表达力的函数式编程特性. 本着知其然,还要知其所以然的学习态度,笔者不禁想到了几个问题. (1)匿名函数(匿 ...

  4. java 匿名委托_委托,匿名方法,λ 表达式

    1.委托:委托本质上就是函数指针,但由于指针过于灵活,因此在很多语言中都采用了更加安全的替代类型,比如Delphi的对象方法和C#的委托.委托使得方法可以做为参数进行传递,极大的方便了程序的处理(事件 ...

  5. .NET中那些所谓的新语法之二:匿名类、匿名方法与扩展方法

    开篇:在上一篇中,我们了解了自动属性.隐式类型.自动初始化器等所谓的新语法,这一篇我们继续征程,看看匿名类.匿名方法以及常用的扩展方法.虽然,都是很常见的东西,但是未必我们都明白其中蕴含的奥妙.所以, ...

  6. 第八节:语法总结(2)(匿名类、匿名方法、扩展方法)

    一. 匿名类 1. 传统的方式给类赋值,需要先建一个实体类→实例化→赋值,步骤很繁琐,在.Net 3.0时代,微软引入匿名类的概念,简化了代码编写,提高了开发效率.  匿名类的声明语法:  var o ...

  7. C#基础17:匿名方法与Lambda表达式

    前文:https://blog.csdn.net/Jaihk662/article/details/96895681(委托) 一.匿名方法 匿名方法:字面理解,没有名字(名字省略)的方法.在开发过程中 ...

  8. Unity学习(C#)——匿名方法(lambda)

    1.匿名方法 匿名方法本质上是一个方法,只是没有名字,任何使用委托变量的地方都可以使用匿名方法赋值 Func<int,int,int> plus=delegate(int arg1,int ...

  9. 雷林鹏分享:C# 匿名方法

    C# 匿名方法 我们已经提到过,委托是用于引用与其具有相同标签的方法.换句话说,您可以使用委托对象调用可由委托引用的方法. 匿名方法(Anonymous methods) 提供了一种传递代码块作为委托 ...

最新文章

  1. CentOS安装PPTP ×××
  2. 用户自定义一个异常,编程创建并抛出某个异常类的实例。运行该程序并观察执行结果。
  3. c#队列取值_C# 队列
  4. 民国大学教授收入有多高?
  5. 游戏编程--wpe封包教程 (新手必备)
  6. 【stm32学习】正点原子stm32f103学习——开发板入门
  7. matlab位图矢量化,位图矢量化的处理算法研究
  8. MongoDB和Compass安装教程
  9. docker安装常用命令docker网络
  10. 文章图片配色怎么选?
  11. mac系统如何显示和隐藏文件
  12. C语言扫雷(可展开)
  13. 【蓝桥杯】基础练习 十六进制转八进制
  14. 大数据计算的四支精干队伍,你造吗
  15. 程序员入职蚂蚁金服第一天就想离职,这并不是个例!
  16. pd.concat() Pandas 数据的拼接
  17. 基于Stm32f103针对TM1640驱动数码管
  18. 实验报告三201521460014
  19. .npy .npz 文件-numpy的文件存储
  20. java版基础排序归并排

热门文章

  1. 转: 视频相关的协议族介绍(rtsp, hls, rtmp)
  2. LoadRunner录制回放常见问题及解决方案
  3. 体积小巧、功能强大的代理工具 -- 3proxy
  4. js、jquery相关的操作
  5. CentOS 安装配置memcached
  6. 内外兼备的企业blog
  7. ASP.net:查找框设默认
  8. #113. 【UER #2】手机的生产
  9. iOS - OC Foundation 框架
  10. HTML Encode 编码在线转换工具