跟小静学CLR via C#(12)-委托Delegate

简介:

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

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


使用委托

老规矩,先上个例子:

image

结果:

image

几点说明:

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

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

编译结果

image

  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并返回。

例如:

image

结果:

image

委托链

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

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

image

结果:

image

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

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

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

image

结果:

image

 

+=、-=

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

image

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

image








    本文转自 陈敬(Cathy) 博客园博客,原文链接

http://www.cnblogs.com/janes/archive/2011/08/24/2152265.html

:,如需转载请自行联系原作者


相关文章
|
2月前
|
C#
C#一分钟浅谈:委托与事件的实现方式
本文详细介绍了C#编程中委托与事件的基础知识及应用场景。首先解释了委托的概念,包括定义与使用方法;接着介绍了事件这一基于委托的特殊类型,展示了如何在类中定义事件及跨类订阅与处理事件;最后讨论了常见问题如事件未处理异常、重复订阅及内存泄漏等,并提出了相应的解决方案。通过本文,读者将全面掌握委托与事件的使用技巧,提升应用程序的设计与开发水平。
109 7
|
3月前
|
编译器 C#
C#中内置的泛型委托Func与Action
C#中内置的泛型委托Func与Action
61 4
|
3月前
|
C#
C#中的委托(一)
C#中的委托(一)
37 1
|
3月前
|
C# C++
C#语言进阶(一)—委托
C#语言进阶(一)—委托
44 0
|
6月前
|
存储 安全 C#
C# - 委托与事件
这篇文档介绍了C#中的委托和事件。委托是存储方法引用的类型,支持回调、事件处理,具有引用方法、类型安全、多播性等特性,并在异步编程中发挥作用。事件是委托的封装,提供保护和订阅机制,防止外部直接访问。当需要在类内部控制方法调用,防止外部误触发时,可使用事件。
|
5月前
|
C#
C#||委托和事件的实例
C#||委托和事件的实例
|
6月前
|
C#
c#委托详解
c#委托详解
37 0
|
6月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
188 3
|
6天前
|
C# 开发者
C# 一分钟浅谈:Code Contracts 与契约编程
【10月更文挑战第26天】本文介绍了 C# 中的 Code Contracts,这是一个强大的工具,用于通过契约编程增强代码的健壮性和可维护性。文章从基本概念入手,详细讲解了前置条件、后置条件和对象不变量的使用方法,并通过具体代码示例进行了说明。同时,文章还探讨了常见的问题和易错点,如忘记启用静态检查、过度依赖契约和性能影响,并提供了相应的解决建议。希望读者能通过本文更好地理解和应用 Code Contracts。
18 3
|
27天前
|
安全 C# 数据安全/隐私保护
实现C#编程文件夹加锁保护
【10月更文挑战第16天】本文介绍了两种用 C# 实现文件夹保护的方法:一是通过设置文件系统权限,阻止普通用户访问;二是使用加密技术,对文件夹中的文件进行加密,防止未授权访问。提供了示例代码和使用方法,适用于不同安全需求的场景。