[《.net框架程序设计》]第十七章 委托

原创 2004年07月07日 15:24:00

第十七章 委托<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

一、             委托的使用

静态委托和实例委托,使用方法类似,这里给出一个使用可变参数委托的例子:

using System;

 

public class DelCls

{

       public delegate void DelDef(params string[] strParams);

 

       public static void CallDel(DelDef dd)

       {

              if(dd != null)   //请务必在此处进行判断,这是个好习惯

              {

                     dd("Hello", "world");

              }

       }

}

 

public class DelIns

{

       //声明为private(私有)成员并不影响在类型内部使用委托

       private static void ClsCallStr(params string[] strParams)     //类型方法

       {

              //将字符串数组并顺序输出

              foreach(string str in strParams)

              {

                     Console.Write("{0} ", str);

              }

              Console.WriteLine();

       }

      

       public void InsCallStr(params string[] strParams)              //实例方法

       {

              //将字符串数组并反序输出

              for(int i = strParams.Length - 1; i >= 0; i --)

              {

                     Console.Write("{0} ", strParams[i]);

              }    

             

              Console.WriteLine();

       }

      

       public static void <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />Main()

       {

              DelIns di = new DelIns();

             

              DelCls.DelDef dd = null;

              Console.WriteLine("combine two delegate:");

              dd += new DelCls.DelDef(DelIns.ClsCallStr);

              dd += new DelCls.DelDef(di.InsCallStr);

              DelCls.CallDel(dd);

             

              Console.WriteLine("remove the first delegate:");

              dd -= new DelCls.DelDef(DelIns.ClsCallStr);

              DelCls.CallDel(dd);

       }

}

 

/*运行结果

combine two delegate:

Hello world

world Hello

remove the first delegate:

world Hello

*/

C#中使用委托方法:

l         创建委托所使用的方法必须和委托声明相一致(参数列表、返回值都一致)

l         利用 +=-=来进行委托的链接或取消链接或直接使用Delegate.CombineDelegate.Remove方法来实现

l         使用MulticastDelegate的实例方法GetInvocationList()来获取委托链中所有的委托

 

二、             委托揭秘

所有的委托都继承自MulticastDelegate,编译器在编译时刻为委托的声明生成了一个完整的委托类,重点注意其中的一些成员:

ü         构造函数,传入委托的目标对象(实例)及指向回调方法的整数

ü         继承自MulticastDelegate_target(System.Object)字段

ü         继承自MulticastDelegate_methodPtr(System.Int32)字段

ü         继承自MulticastDelegate_prevSystem.MulticastDelegaet)字段

ü         生成的与方法声明相一致Invoke函数用以调用方法

可利用MulticastDelegate中的MethodTarget属性来考察_methodPtr_target字段的性质。

关于编译器生成的委托类及Invoke方法的调用情况,可通过使用ILDAsm.exe查看执行文件的IL代码获得

将上例中类型DelIns中的Main方法作如下修改,以实验GetInvocationListMulticastDelegate中属性的使用:

public class DelIns

{

       public static void Main()

       {

             

              Delegate[] arrDel = dd.GetInvocationList();

              foreach(DelCls.DelDef d in arrDel)

              {

                     Console.WriteLine("Object type: {0}, Method name: {1}",

                                                        (d.Target != null) ? d.Target.GetType().ToString() : "null",

                                                        d.Method.Name);  

              }

             

       }

}

/*运行结果

Object type: null, Method name: ClsCallStr

Object type: DelIns, Method name: InsCallStr

*/

三、             委托判等

首先判断_methodPtr_target字段是否相等,若不等则返回false

若相等,继续判断_prev是否为null(指向委托链头部的委托),若为null,则相等返回true;

若不等,继而判断委托链上所有委托对象,重复上述步骤。

 

可见牵涉到委托链的时候是个递归判断的过程

四、             委托链

l         首先被加入到委托链中的委托位于委托链的尾部,但首先被调用,这是因为Invoke中利用递归对委托函数进行调用,这样位于头部的委托最后被调用。

l         委托调用后的返回值,只是最后一次被调用方法的返回值,即委托链头部委托的返回值

l         每调用一次Remove方法只删除匹配的第一个委托链

五、             委托与反射

       以下是.net framework sdk文档提供的Delegate.CreateDelegate方法列表:

创建指定类型的委托以表示指定的静态方法。

[C#] public static Delegate CreateDelegate(Type, MethodInfo);

创建指定类型的委托,该委托表示要对指定的类实例调用的指定实例方法。

[C#] public static Delegate CreateDelegate(Type, object, string);

创建指定类型的委托,该委托表示指定类的指定静态方法。

[C#] public static Delegate CreateDelegate(Type, Type, string);

创建指定类型的委托,该委托表示要按指定的大小写敏感度对指定类实例调用的指定实例方法。

[C#] public static Delegate CreateDelegate(Type, object, string, bool);

 

下面的示例演示了创建静态方法委托、实例方法委托以及动态调用委托:

using System;

using System.Reflection;

 

public class DelReflection

{

       public delegate void GoGo(string strPam, Int32 nPam);

      

       public static void ClsGo(string strPam, Int32 nPam)

       {

              Console.WriteLine("In class, String:{0}, Int32:{1}", strPam, nPam);

       }

      

       public void InsGo(string strPam, Int32 nPam)

       {

              Console.WriteLine("In instance, String:{0}, Int32:{1}", strPam, nPam);

       }

      

       public static void Main()

       {

              Delegate d = null;

             

              d = Delegate.CreateDelegate(typeof(GoGo), typeof(DelReflection), "ClsGo");

              if(d != null)

                     d.DynamicInvoke(new Object[]{"Hello", 45});          

                    

              DelReflection dr = new DelReflection();

              d = Delegate.CreateDelegate(typeof(GoGo), dr, "InsGo");

              if(d != null)

                     d.DynamicInvoke(new Object[]{"Hello", 45});          

       }

}

/*运行结果

In class, String:Hello, Int32:45

In instance, String:Hello, Int32:45

*/

《.NET框架程序设计》第十七章 委托

第十七章 委托 一、委托的使用静态委托和实例委托,使用方法类似,这里给出一个使用可变参数委托的例子:using System; public class DelCls{       public de...
  • Ninth
  • Ninth
  • 2004年08月29日 12:29
  • 1719

终于把Microsoft .NET框架程序设计(修订版)看完了

这本书是由windows & .Net专家Jeffrey Richter写的,现在最新的是第二版CLR Via C#。虽然内容差不了多少,不过俺还是买了。:D。此书由李建忠老师翻译的。   Jeff...
  • kisserLeon
  • kisserLeon
  • 2006年11月28日 19:09
  • 1874

.NET框架程序设计——体系结构

谈到.NET,相信对于大多数初学者而言,都会感觉比较乱、比较迷茫,什么ASP.NET、VB.NET、VC.NET、ADO.NET、.NETFramework 等等概念,搞的我们晕头转向的,他们之间到底...
  • dongyue786
  • dongyue786
  • 2014年10月15日 15:47
  • 1983

.net框架程序设计读书笔记二(Microsoft .net 框架开发平台体系架构)

第一章:Microsoft .net 框架开发平台体系架构    本章的目标:对.net框架体系架构有一个总体的认识,并对.net框架中出现的一些新的技术和术语有一个基本的了解。 1.1 将源代码编译...
  • cwbboy
  • cwbboy
  • 2004年05月31日 16:57
  • 999

[C#]委托和事件(详细讲解)

引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没...
  • s10141303
  • s10141303
  • 2014年03月02日 00:23
  • 4317

.NET学习笔记(八) ------委托(上)

过年后就一直没写学习笔记了,书第一边已经看完了,后面从事件开始的章节有些复杂,牵扯的知识也很 多。而且最近工作也很忙,所以没有时间来写。这段时间感觉自己对委托又有了一定的认识,所以打算来聊聊 .net...
  • cc_net
  • cc_net
  • 2008年05月21日 22:42
  • 3146

学习《.net框架 程序设计》学习笔记---委托(一)

   一.认识委托      在.net框架中,回调函数任然像在非托管windows编程中一样有用和普遍。但是,.net框架为回调函数提供了一种称为委托(delegate)的类型安全的机制。     ...
  • zyxfcb1520
  • zyxfcb1520
  • 2011年06月21日 23:12
  • 424

.net 自带的两个内置委托

#region Action与Func内置委托 //--------------无返回值的委托--------------------------- ...
  • xiaogechengxuyuan
  • xiaogechengxuyuan
  • 2016年03月01日 19:35
  • 509

.Net4.0用表达式树构建委托改善反射性能

转自:  http://www.cnblogs.com/lemontea/archive/2013/02/04/2891281.html 最近搞一个系统时由于在比较关键地方用到反射了...
  • daonidedie
  • daonidedie
  • 2014年11月27日 10:39
  • 847

什么时候该用委托,为什么要用委托,委托有什么好处

好多人一直在问:什么时候该用委托,为什么要用委托,委托有什么好处.... 看完下面的文章你将茅塞顿开..(看不懂的直接TDDTDS) 概念虽然我不喜欢讲太多 我们直接先来YY 个场景: 我很喜...
  • cheungbill
  • cheungbill
  • 2012年06月24日 18:21
  • 8311
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[《.net框架程序设计》]第十七章 委托
举报原因:
原因补充:

(最多只允许输入30个字)