委托的本质就是一个类,在可以定义类的地方都可以声明委托。

定义一个委托:

internal delegate void MyDelegate(int value);

编译器实际上会像下面这样定义一个完整的类:

internal class MyDelegate : System.MulticastDelegate

{

     public MyDelegate(Object object, IntPtr method);

     public virtual void Invoke(int value);

     public virtual IAsyncResult BeginInvoke(int value, AsyncCallback callback, Object object);

     public virtual void EndInvoke(IAsyncResult result);

}

注意,多路广播委托声明时必须返回void,否则返回值不知道应该送回什么地方。对此,我做了一个测试:如果不将委托的声明返回void,则返回值返回的是最后一个链入委托链的方法的返回值,编译不会出错

协变和反协变

将一个方法绑定到一个委托时,C#CLR都允许引用类型的协变(convariance)和反协变(contra-variance)。协变指的是一个方法能返回从委托的返回类型派生的一个类型。反协变指的是一个方法的参数类型可以是委托的参数类型的基类。例如下面这个委托:

delegate object MyCallback (FileStream s);

对于具有如下原型的方法:

string SomeMethod(Stream s);

这里,SomeMethod的返回类型(string)继承自委托返回类型(object)。这种协变是允许的。SomeMethod的参数类型(Stream)是委托的参数类型(FileStream)的基类,这种反协变是允许的。

注意,协变和反协变只能用于引用类型,不能用于值类型或void

为什么要用委托
  使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与CC++中的函数指针不同,委托是面向对象,而且是类型安全的

委托出现的地方

委托经常出现的场合:1、事件调用(最常用)。2、线程调用。3、同步异步调用。4、匿名方法。5、回调方法。

委托和事件

事件就是一种特殊的委托,用event关键字申明。实际上,event体现了封装性。event就是两个方法——addremove组成的,当你写下button1.Click+=XXX的时候,其实就是使用了eventadd方法。而-=就调用了remove方法。就和属性的get/set方法思想是一样。这样做的目的就是,事件从对象外部只能够增加新的响应方法,删除已知响应方法,而不能引发事件,或者获取其他人注册的响应方法等信息。而使用delegate共有字段则不能做出这些限制


参考文章:C#委托之个人理解 http://www.cnblogs.com/michaelxu/archive/2008/03/31/1131500.html

                   C#中的委托和事件 http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html

                   装配脑袋 在 http://www.cnblogs.com/michaelxu/archive/2008/04/02/1134217.html 中16楼回复

作者: Little Prince 发表于 2011-08-23 17:26 原文链接

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"