本来按照进度应该学习事件了,可总觉得应该委托在前,事件在后,才好理解。

委托是一个类,它提供了回调函数机制,而且是类型安全的。使用委托可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,提高了程序的可扩展性。


使用委托

老规矩,先上个例子:

结果:

几点说明:

  1. 使用关键字delegate声明委托。委托是类型安全的,定义时其返回值类型、参数个数及参数类型要和想要调用的方法兼容。
  2. 在这个例子中,通过Introduce方法获取对delegateIntroduce委托对象的引用。委托对象相当于方法的包装器,使方法能通过包装器进行间接回调。
  3. 委托即允许调用静态方法(如①②),还允许调用实例方法(③)。
  4. 将一个方法绑定到委托时,允许引用类型的协变性和逆变性。(ps:陌生的词汇…)
  • 协变性:方法能返回委托类型的派生类型;
  • 逆变性:方法获取的参数可以是委托类型参数的基类。

注意:这两点只限于引用类型,不能用于值类型或者void。

编译结果

  1. 委托实际上会编译成一个类,包含四个方法:.ctor, Invoke, BeginInvoke, EndInvoke。
  2. 所有的委托都会自动继承类System.MulticastDelegate。 MulticastDelegate又继承自Delegate。
  3. MulticastDelegate类提供了三个公共字段:

名称

类型

说明

_target

System.Object

当委托调用静态方法时,该字段为null。当委托调用实例方法时,表示回调方法要操作的对象。

_methodPtr

System.InPtr

标识要回调的方法

_invocationList

System.Object

通常为Null,在委托链时可以引用一个委托数组

4.    Delegate类提供了两个只读属性:

  • Target   :返回字段_target的值
  • Method :将字段_methodPtr的值转换为MethodInfo并返回。

例如:

结果:

委托链

委托链是由委托对象构成的一个集合。这样就可以将多个方法绑定到同一个委托,调用这个委托的时候会依次调用其所绑定的方法。

接着上面的例子,我们修改Main方法的调用:

结果:

构造委托链时,用到了两个静态方法:

  • Delegate.Combine(d1,d2) :将委托添加到委托链中。其间_invocationList字段会初始化为一个委托对象数组。上面例子构造完成后该_invocationList[0]被初始化为di1所引用的委托,以此类推。在执行时,发现_invocatonList字段不为空,则会遍历数组元素,顺序调用每个委托包装的方法。
  • Delegate.Remove (d1,d2) :从d1的委托数组中字段中查找_target和_methodPtr字段与d2匹配的委托,找到后移除。即使匹配记录有多个,每次也只移除一个。

另外,MulticastDelegate类还提供了GetInvocationList()方法,来查看委托链中的委托数组。例如我们将调用委托的Introduce方法略作修改:

结果:

+=、-=

C#为委托的+=和-=操作符进行了重载,来简化语法。

执行结果相同。查看IL代码就会发现他们实际调用的是Combine和Remove方法。


THE END.

下次再碰上笔试或者面试的就不用紧张兮兮的了,可以洋洋洒洒的说一通了。

委托:http://www.cnblogs.com/xcj26/p/3536082.html

http://www.cnblogs.com/DeepLearing/p/4594518.html

http://www.cnblogs.com/max198727/p/3436220.html

闭包:http://www.cnblogs.com/jiejie_peng/p/3701070.html

你也许喜欢:跟小静读CLR via C#(00)-开篇及目录

CLR via C#(12)-委托Delegate的更多相关文章

  1. [CLR via C#]17. 委托

        回调函数是一种非常有用的编程机制,它已经存在很多年了.Microsoft .NET Framework通过委托(delegate)来提供一种回调机制.不同于其他平台(比如非托管C++)的回调机 ...

  2. 深入理解委托(Delegate)

    前言 委托其实一直以来都感觉自己应该挺熟悉的,直到最近又去翻了翻 CLR via C#,感觉我之前的理解可能还有失偏颇.在这记录一下. 之前文章的链接: 接口和委托的泛型可变性 C#高级编程笔记 De ...

  3. [.NET] C# 知识回顾 - 委托 delegate (续)

    C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...

  4. [C#] C# 知识回顾 - 委托 delegate

    C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...

  5. C# 委托Delegate(一) 基础介绍&用法

    本文是根据书本&网络 前人总结的. 1. 前言 定义&介绍: 委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的 ...

  6. 为什么不能把委托(delegate)放在一个接口(interface)当中?

    stackoverflow上有人问,为什么不能把委托放在一个接口当中? 投票最多的第一个答案第一句话说,“A Delegate is just another type, so you don't g ...

  7. C# 代理/委托 Delegate

    本文转载自努力,努力,努力 1. 委托的定义:委托是函数的封装,它代表一"类"函数.他们都符合一定的签名:拥有相同的参数列表,返回值类型.同时,委托也可以看成是对函数的抽象,是函数 ...

  8. c# 委托 delegate

    委托是一种存储函数引用的类型,在事件和事件的处理时有重要的用途 通俗的说,委托是一个可以引用方法的类型,当创建一个委托,也就创建一个引用方法的变量,进而就可以调用那个方法,即委托可以调用它所指的方法. ...

  9. 理解委托(delegate)及为什么要使用委托

    理解委托(delegate)及为什么要使用委托 委托:是一种定义方法签名的类型. 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联. 您可以通过委托实例调用方法. 上述为官方说法,理解起来 ...

  10. C# -- 使用委托 delegate 执行异步操作

    C# -- 使用委托 delegate 执行异步操作 委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似. 与 C 中的函数指针不同,委托是面向对象的.类型安全的和保险的. 委托的 ...

随机推荐

  1. iOS开发——UI基础-懒加载,plist文件,字典转模型,自定义view

    一.懒加载 只有使用到了商品数组才会创建数组 保证数组只会被创建一次 只要能够保证数组在使用时才创建, 并且只会创建一次, 那么我们就称之为懒加载 lazy - (void)viewDidLoad 控 ...

  2. WinForm多线程编程简单Demo

    需要搭建一个可以监控报告生成的CS(WinForm)工具,即CS不断Run,执行获取数据生成报告,经过研究和实践,选择了使用"WinForm多线程编程"的解决方案.当然参考了园中相 ...

  3. HTML页面的布局

    1.纵向切分页面:CSS POSITION的默认值为:STATIC 1) <html> <head> <title>Hello</title> < ...

  4. 使用WITH AS提高性能简化嵌套SQL

    一.WITH AS的含义 WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候,是为了让 ...

  5. hadoop初识

    搞什么东西之前,第一步是要知道What(是什么),然后是Why(为什么),最后才是How(怎么做).但很多开发的朋友在做了多年项目以后,都习惯是先How,然后What,最后才是Why,这样只会让自己变 ...

  6. 查看Android应用包名package和入口activity名称

    使用android自动化测试工具启动应用时,需要填写被测程序的包名和启动的Activity,以下有两种查看应用包名package和入口activity名称的方法: 方法一:使用aapt    //aa ...

  7. python判断文件和文件夹是否存在

    import osos.path.isfile('test.txt') #如果不存在就返回Falseos.path.exists(directory) #如果目录或文件不存在就返回False

  8. 【转】Nginx服务器的反向代理proxy_pass配置方法讲解

    [转]Nginx服务器的反向代理proxy_pass配置方法讲解 转自:http://www.jb51.net/article/78746.htm 就普通的反向代理来讲Nginx的配置还是比较简单的, ...

  9. Delphi中限制文本框(TEdit)只能输入数字

    procedure Tform1.Edit1KeyPress(Sender: TObject; var Key: Char);var edt: TEdit; str, strL, strR: stri ...

  10. 关于TxQBService报的错,腾讯你真牛B啊

    腾讯你真牛B啊,浏览器都7了,还特么的报这么低级的错误,还每10秒写一条windows日志,让人有什么心情用你的浏览器,滚.