王朝网络
分享
 
 
 

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

王朝c#·作者佚名  2006-01-30
宽屏版  字体: |||超大  

第十七章 委托

一、 委托的使用

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

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 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.Combine和Delegate.Remove方法来实现

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

二、 委托揭秘

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

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

ü 继承自MulticastDelegate的_target(System.Object)字段

ü 继承自MulticastDelegate的_methodPtr(System.Int32)字段

ü 继承自MulticastDelegate的_prev(System.MulticastDelegaet)字段

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

可利用MulticastDelegate中的Method及Target属性来考察_methodPtr及_target字段的性质。

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

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

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

*/

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有