委托

在C++中可以利用“函数指针”将对方法的引用作为实参传递给另一个方法,而C#中可以利用委托提供相同的功能。

委托-内部机制

但是委托实际上是一个特殊的类。委托必须直接或间接的派生自System.Delegate。实际的委托类型总是派生自System.MulticastDelegate(创建委托的时候,编译器自动继承的是MulticastDelegate而不是Delegate),后者又从Delegate派生。

委托内部包含了几个重要的属性:第一个就是System.Reflection.MethodInfo类型的,它描述了特定方法的签名,包括方法名称、参数和返回类型。除了MethodInfo,委托还需要一个对象实例,其中包含了要调用的方法,这是第二个属性Target的作用。(如果是静态方法,则Target对应类型自身)。

Func和Action

为了减少自定义委托类型的必要,.NET 3.5包含了一组通用的委托,其中大多数都是泛型。System.Func系列委托代表有返回值的方法,而System.Action表示返回void的方法。


Public delegate void Action(); Public delegate void Action<in T>(T arg) Public delegate void Action<in T1,in T2>(in T1 arg1,in T2 arg2) Public delegate void Action<in T1,in T2,in T3>(in T1 arg1,in T2 arg2,in T3 arg3) ……. Public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16>(T1 arg1,T2 arg2,T3 arg3,T4 arg4,T5 arg5,T6 arg6,T7 arg7,T8 arg8,T9 arg9,T10 arg10, T11 arg11,T12 arg12, T13 arg13, T14 arg14,T15 arg15, T16 arg16) Public delegate Tresult Func<out TResult>(); Public delegate Tresult Func<in T,out TResult>(T arg); Public delegate Tresult Func<in T1,in T2,out TResult>(T1 arg1,T2 arg2); …… Public delegate Tresult  Func<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,out TResult>(T1 arg1,T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6,T7 arg7,T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15,T16 arg16)

事件

说到事件,得知道委托的几个缺陷:

1、在使用+=赋值操作符时使用了=,会导致一个全新的委托链代替了前面链,这是一个十分容易犯的错误,所以event提供了额外的封装,避免不小心取消了其他订阅者。

2、可以在委托包容类的外部调用委托,这是由于委托的封装不充分。

3、普通委托还有一个不利之处在于,很容易忘记在调用委托之前检查null值(在C#6中使用 ?.  null条件操作符),这会引发一个异常。

而事件就可以很简单的理解了,就是对委托的进一步封装,解决了委托存在的一些缺陷。

事件-内部机制

事件限制外部类只能通过+=操作符向发布者添加订阅方法,并用-=操作符取消订阅,除此之外什么都不能做。此外,还禁止除包容类之外的任何其他类调用事件。为了达到上述目的,C#编译器会获取带有event修饰符的public委托变量,并将委托声明为private。此外,它还会添加两个方法和两个特殊的事件块,这里就不展开了。

最新文章

  1. awk命令详解
  2. LruCache缓存
  3. ADB am 命令详细参数
  4. Linux解压命令(tar)
  5. struts2笔记4
  6. resque 遍历加载job目录下的类
  7. Listview 隐藏item
  8. 从电商平台促销活动看电商app开发趋势
  9. ptypes中string类的空间分配
  10. 【Selenium】自动化调试后C盘越来越大
  11. IT人员应该怎么跳槽
  12. 谓词--Predicate
  13. 使用DiskGenius对虚拟机磁盘进行压缩
  14. 表与表的关系把RD搞乱了,记一个Procedure中的bug
  15. IE浏览器下ajax和缓存的那些事儿
  16. 用CSS画基本图形
  17. websocketd
  18. 微信小程序 学习资料
  19. Android中糟糕的AsyncTask
  20. nagiosQL访问时报错PHP message: PHP Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead

热门文章

  1. DevOps|高效能敏捷交付组织:特性团队(FeatureTeam)+Scrum
  2. JavaScript基础复盘补缺
  3. 一个实用的 vite + vue3 组件库脚手架工具,提升开发效率
  4. 在ubuntu 上安装golang
  5. 线上Electron应用具备哪些特征?
  6. clickhouse在风控-风险洞察领域的探索与实践
  7. Emgu实现图像分割
  8. 2022-11-12 Acwing每日一题
  9. php统一的gocheck方法
  10. 春秋云境 CVE-2022-24663复现