委托的问题 - 用委托实现回调

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013542549/article/details/52554036

C#委托的问题 - 用委托实现回调


今天看到一个非常好的小例子,内容是这样:


我:”儿子,去把院子里的草割一下,我想读会儿书。”

儿子:“爸爸,我已经把院子打扫干净了。”

儿子:“爸爸,我给割草机加好油了。”

儿子:“爸爸,割草机启动不了。“

我:”我来看看。“

儿子:”爸爸我昨完了。“


上面这段很短的交流掩饰了回调(CallBack)的概念。我给儿子一个任务,他在完成任务期间不断地打断我。在等待他完成任务的每一步骤时,我不需要停下自己的工作。当他有一个重要(或者不重要)的状态需要报告,或者需要我的协助时,他可以不时地打断我。回调可为服务器和客户机之间提供异步的反馈。其中可能会牵扯到多线程,或者需要为同步更新提供一个入口点,在C#中,回调是用委托来实现的。

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

回调和委托在C#中非常常用,以至于C#特地的以lambda表达式的形式为其提供了精简的语法。此外,.NET Framework还是用Predicate<T>  ,  Action<> Func<>内建了很多常用的委托形式。Predicate<T>表示一个提供bool类型返回值的函数,用来测试某个条件。Func<>将接受一系列的参数,并返回单一的结果。可以看到,Func<T , bool>的含义其实和Predicate<T>是一样的。但是编译器不会将Predicate<T>Func<T,bool>当成同样的语句来处理。最后Action<>可以接受任意数目的参数,但不返回任何值。


LINQ中大量地使用了这样的概念。List<T>中也包含了很多讲用到回调的方法,例如下面这段代码:


List<Int> numbers = Enumerable.Range(1,200).ToList();
var oddNumbers = numbers.Find(n=> n%2 ==1);
var test = numbers.TrueForAll(n => n  < 50);
number.RemoveAll(n => n%2 ==0);
number.ForEach(item => Console.WriteLine(item));

Find()方法将以Predicate<int>的形式接受一个委托,注意检查列表中的每一个元素,这是个简单的回调。Find()方法使用该毁掉检查每个元素,并返回通过检验逻辑的个数。编译器将接受并把该lambda表达式转换成委托,然后用委托来实现回调。

TrueForAll() 与其类似,也会检查每个元素,并判断是否每个元素都通过了检查,RemoveAll()则从列表中移除所有满足指定条件的元素。

最后,List.ForEach()方法将在列表的每一个元素上执行某些动作。与前面一样,半年一起将5把lambda表达式转换成方法,然后创建一个委托,指向该方法。



阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页