博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Effective C#》读书笔记——条目24:用委托实现回调<使用C#表达设计>
阅读量:4921 次
发布时间:2019-06-11

本文共 1971 字,大约阅读时间需要 6 分钟。

  在C#语言中,回调是通过委托来实现的。委托为我们提供了安全的回调定义,大多数委托都和事件相关,但这不是委托的全部应用场景,当类之间需要通信,并且我们希望一种比接口更加松耦合的机制时,委托便是最佳选择。委托允许我们在运行时配置目标并且通知多个客户对象,委托对象中包含一个引用,该方法可以使静态方法也可以是实例方法。使用委托,我们可以和一个或者多个在运行时联系起来的客户对象进行通信。

 

Lambda表达式

  回调和委托在C#中非常常用,C#为委托提供了精简的语法——Lambda表达式。同时.NET还内建了很多常用的委托形式,它们包含在这三个泛型委托中:

  • :表示一个提供bool返回值的函数,用来测试某个条件。
  • :接收一系列参数,但不返回任何值。
  • :接收一系列参数,返回单一结果。

 Linq中大量使用了这些概念,List<T>中也包含了很多的回调方法,如下:

1         static void Main(string[] args) 2         { 3             List
numbers = Enumerable.Range(1, 200).ToList(); 4 var oddNumbers = numbers.Find(n => n % 2 == 1);//返回集合中匹配的第一个元素 5 var test = numbers.TrueForAll(n => n < 50);//是否集合中每个元素符合定义的条件,返回false 6 numbers.RemoveAll(n => n % 2 == 0);//删除所有偶数 7 numbers.ForEach(item => Console.WriteLine(item));//打印集合中所有元素 8 9 Console.Read();10 }

   LINQ所有的功能都依赖于委托。回调也是用在WPF和Windows Forms中跨线程调用的封装(marshalling)上。在.NET Framework中需要传入方法的地方,框架都会使用委托,并允许调用者使用Lambda表达式提供。

 

多播委托

   C#中的委托都是多播委托(multicast delegate)。多播委托将会把所有添加到委托中的目标函数组合成一个单一的调用。在这里我们需要注意两点

1.如果有委托调用出现异常,那么委托链会被中断,这种方式不能保证安全。

2.多播委托返回的将是委托链上最后一个函数调用的返回值。

 为了解决上的问题我们可以手动遍历委托链中的每个委托目标(可以参考:),通过调用委托实例的GetInvocationList(),遍历委托链中的每个目标。看下面的示例:只有每一个委托调用都返回true时,遍历才能继续。或者我们可以再遍历委托链时添加try/catch语句块,处理异常。

1         public void LengthyOperation(Func
Pred) 2 { 3 bool bContinue = true; 4 foreach (ComplicatedClass cl in container) 5 { 6 c1.DoLengthyOperation(); 7 foreach (Func
pr in Pred.GetInvocationList()) 8 { 9 bContinue &= pr();//等效于 bContinue = bContinue & pr();10 11 if (!bContinue)12 return;13 }14 }15 }

 

小节

委托是在运行时进行回调的最好方式,这种方式对客户类的要求更加简单,你可以在运行时配置委托目标。另外,委托也支持多个客户目标。在.NET中,客户回调应该使用委托来实现。

转载于:https://www.cnblogs.com/IPrograming/archive/2013/01/17/EffectiveCSharp_24.html

你可能感兴趣的文章
[Python]小甲鱼Python视频第027课(集合:在我的世界里,你就是唯一)课后题及参考解答...
查看>>
sed
查看>>
关系数据库-----SQL标准语言
查看>>
java设计模式----中介模式
查看>>
常用通用JS函数
查看>>
第一章 读后心得体会
查看>>
windows下命令行cmder工具
查看>>
【深度学习大讲堂】首期第一讲:人工智能的ABCDE 第二部分:简谈当前AI技术与发展趋势...
查看>>
pandas 3 设置值
查看>>
pip无法更新
查看>>
vue-12-element组件库
查看>>
尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
查看>>
安装oracle后登录时出现 ERROR: ORA-01031 insufficient privileges
查看>>
HOME键窥探Android的Activity生命周期
查看>>
Regularization - Handle with the Overfitting Problem
查看>>
领域驱动设计和实践
查看>>
【第二章】Shell 变量
查看>>
Docker概念学习系列之为什么使用docker?(3)
查看>>
2.1 Producer API官网剖析(博主推荐)
查看>>
win10系统自带的浏览器ME如何将网页转成PDF
查看>>