委托属于C#中的新名词,它的应用也非常广泛,例如事件就是委托最简单而又直接的例子。

那么首先说说什么是委托,其实委托在用过C或者C++的人看来就是函数指针,不过使用C#的大多数人都没有用过这两门语言,因此对委托的理解不是很深,对于委托可以简单的从字面去理解,即“委托别人去执行某些操作”,也就是说执行一个操作,而这个操作过程自身并不知道,只是委托过来让你去执行而已。

参看如下这个例子。

public delegate void HelloHandler( string Msg );

private void SayHello( string sMsg )

{

MessageBox.Show( sMsg );

}

// delegate sample

HelloHandler hHello = new HelloHandler( SayHello );

hHello( "Hello World!" );

例子很明显,在执行hHello的时候,并不知道具体的过程是什么样的,只是去执行而已。

现在要说说委托能做些什么,那么先来分析一下事件,这也是委托用得最多的地方。一般事件的初始化需要绑定一个事件处理函数,那么当事件触发的时候,处理函数会被调用,也就是说在事件处理函数可以明确的知道,此事件是被触发了。例如,点击窗体的上的Button,它会把Click事件反馈给窗体。很明显,委托是处理对象之间的信息交互。除了事件外,委托的大多用处都和此类似,那么这样使用的好处在于降低对象之间耦合性。

其次委托不同于以前函数指针的地方在于,可以绑定多个委托函数,例如:

public delegate void HelloHandler( string Msg );

private void WriteHello1( string sMsg )

{

Debug.WriteLine( "WriteHello1:" + sMsg );

}

private void WriteHello2( string sMsg )

{

Debug.WriteLine( "WriteHello2:" + sMsg );

}

// delegate sample

HelloHandler hHello = new HelloHandler( WriteHello1 );

hHello += new HelloHandler( WriteHello2 );

hHello( "Hello World!" );

不过在这种情况下,由于绑定到委托上的函数是按照顺序执行的,所以有两个潜在的问题。

第一个问题,当一个函数执行过程中产生异常,导致后面的不能进行执行。就上面的例子而言,如果在“WriteHello1”函数中出现异常,会导致“WriteHello2”不能被执行。

另一个问题,就是委托执行的返回值,当绑定多个函数,委托执行的返回值是最后一个绑定函数执行后的返回值,那么通过这个值去做判断将会是不正确的。

那么对于委托绑定多个函数,要注意的是不要把异常扩散出来,其次委托类型的返回值为“void”。

如何去使用委托,很多人看了书上的例子,也知道委托的意义,但是无法把它和实际应用进行结合。那么在使用委托的时候,首先要明白几个问题,等各个问题清楚了,委托原型也就自然出来了。

需要分析清楚的问题有如下几点。

问题一,传递信息是什么,传递的时机是否固定,一次传递还是多次传递;

问题二,用委托是否合适;

问题三,哪一方是委托的调用端,而哪一方是委托的初始端;

问题四,委托的初始化放在哪里比较合适。

问题一是关键,这首先决定是否要使用委托来实现,其次如果要使用委托,那么需要确定委托函数类型。

对于问题二来说,很多人可能就不解了。没错,委托是可以降低类型之间的耦合性,但是能起到这种作用的并不是只有委托这一种方法。很多情况下,用重载构造函数即可以达到这一目的,因此想问题的时候,不能局限于此。例如,很多人都做过弹出一个单独窗体对某一条记录进行修改,这里用委托可以实现,但是考虑到DataRow属于引用类型,而这个窗体脱离了数据记录就失去了意义,因此可以重载构造函数,在初始化窗体的时候,把记录传递给窗体就行了。相对而言,后者会更简单直接些。

有了前两个问题的分析,不少人在写委托的时候,会把顺序写反了,因此程序执行的效果并不是设想中的那样,这一点要尤为注意。

对于第四个问题来说,可以借鉴窗体的控件事件初始化部分代码,即委托的初始化采取就近原则,不过这不是唯一初始化的地方,这样写只是便于防止漏写。

好了,对于委托大致说这么多,希望对大家有所帮助。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Knight94/archive/2006/11/15/1385284.aspx

转载于:https://www.cnblogs.com/Sue_/articles/1656797.html

《Effective C#》Item 21:用委托实现回调相关推荐

  1. 21.使用委托表达回调

    回调用于为服务器和客户端之间提供异步的反馈,其中可能会涉及到多线程或者需要提供一个入口点用于同步更新,在C#中,我们使用委托来表达回调. 委托为我们提供了类型安全的回调定义,虽然大多数常见的委托应用都 ...

  2. Effective JavaScript Item 23 永远不要修改arguments对象

    本系列作为Effective JavaScript的读书笔记. arguments对象只是一个类似数组的对象,但是它并没有数组对象提供的方法,比如shift,push等.因此调用诸如:argument ...

  3. Effective C#: Item 1 Always use properties instead of accessible data members

    Effective C#: Item 1 Always use properties instead of accessible data members Item 1: 当设计类时,永远用Prope ...

  4. Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!...

    开篇:要想理解Block和委托,最快的方法是搞明白"回调函数"这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名 ...

  5. Effective JavaScript Item 37 认识this的隐式指向

    本系列作为Effective JavaScript的读书笔记. CSV数据通常都会被某种分隔符进行分隔.所以在实现CSV Reader时,须要支持不同的分隔符.那么,非常自然的一种实现就是将分隔符作为 ...

  6. 读书笔记 effective c++ Item 50 了解何时替换new和delete 是有意义的

    1. 自定义new和delete的三个常见原因 我们先回顾一下基本原理.为什么人们一开始就想去替换编译器提供的operator new和operator delete版本?有三个最常见的原因: 为了检 ...

  7. 读书笔记 effective c++ Item 49 理解new-handler的行为

    1. new-handler介绍 当操作符new不能满足内存分配请求的时候,它就会抛出异常.很久之前,它会返回一个null指针,一些旧的编译器仍然会这么做.你仍然会看到这种旧行为,但是我会把关于它的讨 ...

  8. 读书笔记 effective c++ Item 18 使接口容易被正确使用,不容易被误用

    1. 什么样的接口才是好的接口 C++中充斥着接口:函数接口,类接口,模板接口.每个接口都是客户同你的代码进行交互的一种方法.假设你正在面对的是一些"讲道理"的人员,这些客户尝试把 ...

  9. 读书笔记 effective c++ Item 34 区分接口继承和实现继承

    看上去最为简单的(public)继承的概念由两个单独部分组成:函数接口的继承和函数模板继承.这两种继承之间的区别同本书介绍部分讨论的函数声明和函数定义之间的区别完全对应. 1. 类函数的三种实现 作为 ...

最新文章

  1. SQL Server分页查询方法整理
  2. C++ 基础知识!初学者必看!
  3. [剑指offer]面试题18:树的子结构
  4. java scala 获取类_在Scala 2.10中获取java.lang.Class [T]的Scala类型
  5. HTML如何实现单元格自动编号,如何在Excel中自动为列编号?
  6. ado mysql 读写_C#使用Ado.Net读写数据库
  7. android手机禁止休眠_浮窗----手机是否可以一心多用?这个只是开始而已。
  8. Java和JavaScript在网页设计中的区别,了解一下吧
  9. golang日志服务器_golang 写日志到syslog
  10. 中国幻想向欧美妥协取得5G权益将是一种错误
  11. python julia go_Python的四个挑战者:Swift、Go、Julia、R
  12. x264代码剖析笔记
  13. 如何防止三分钟热度?给自己的目标定个阶段性奖励吧
  14. 【anaconda】Multiple Errors Encountered与安装包graphviz失败
  15. java基于微信小程序的物流仓储系统 uniapp 小程序
  16. 团队协作方法之:高效使用任务故事墙
  17. 使用weixin-java-miniapp配置进行单个小程序的配置
  18. 测试家里网速用什么软件,家中宽带网速多少?教你测试小妙招
  19. 扔掉信用卡的10个理由
  20. c语言判断一个数是否为偶数源代码,c语言判断一个数是否为偶数

热门文章

  1. java批量处理数据库语句_Java项目中调用bat批处理进行多用户数据库备份
  2. 有意思的C语言运算符
  3. mysql内部损坏_mysql表损坏故障案例
  4. 优化自定义函数_Pandas常见的性能优化方法
  5. ambari mysql error code: 1665_ambari安装中常见的问题
  6. pandas用众数填充缺失值_7步搞定数据清洗-Python数据清洗指南
  7. Dell笔记本双系统安装(Ubuntu 16.04)
  8. RS-485总线HUB中继器产品性能特点介绍
  9. 为什么要使用工业以太网交换机?
  10. 工业以太网交换机的软件故障