收藏本站
设为主页
联系站长
欢迎光临  | 网站首页 | 编程技术 | 网络技术 | 建站技术 | 数据库技术 | 软件应用 | 硬件技术 | 下载中心 | 睿学论坛 |  {$Wap} Welcome to RuiXue
您现在的位置: 睿学电脑技术网 >> 编程技术 >> C# >> 正文
  介绍.NET 中的委派(D elegates)之三    热      【字体:小 大】
介绍.NET 中的委派(D elegates)之三
作者:互联网    编程技术来源:互联网    点击数:    更新时间:2008-10-22    

睿学电脑专家提供,编程技术,SEO技术,网站技术,建站技术,软件应用,网上赚钱,提高流量,网络安全交流

因为所有的委派都派生于MulticastDelegate,它们继承了MulticastDelegate的域,属性和方法。在所有这些成员中,你要特别注意三个私有(private)域:

用于委派类型的私有域:

域 类型 描述
_target System.Object 指回调函数被调用时应该操作的对象。用于实例方法回调
_methodPtr System.Int32 内部整型,CLR用它来标示被回调的方法
_prev System.MulticastDelegate 指另一个委派对象,通常为null



   所有的委派都有代两个参数的构造器:一个参数是对象引用,一个是指代回调方法的整型。但是,如果你检查源代码,就会发现明白诸如App.FeedbackToConsole 或 appobj.FeedbackToFile的传递使用值进行的。你的敏感会告诉你这个代码不能编译!

   然而,编译器知道某个委派被创建,同时编译器解析源代码以决定引用哪个对象和方法。对象引用被传递为目标参数,并且用某个特定的Int32值(从某个MethodDef或MethodRef元数据符号获得)标示的方法被传递为methodPtr参数。对于静态方法,null被传递为目标参数。在构造器内部,这两个参数被存储在它们对应的私有(private)域中。

   另外,构造器将这个域置为null。这个域被用来创建一个MulticastDelegate对象链表。现在我们暂时忽略_prev域,在后续文章中将会详细讨论有关它的内容。

 每一个委派对象实际上就是一个方法包装器,当方法被调用时,受作用的对象被操作。MulticastDelegate类定义两个只读公共实例属性:Target和Method。给定一个委派对象引用,你就可以查询到它的这些属性。如果方法被回调,Target属性返回一个对将要操作的对象的引用。如果方法是静态的,则Target返回null。Method属性返回标示回调方法的System.Reflection.MethodInfo对象。

   你可以用几种方式使用这些信息。一种方式是检查是否某个委派对象引用特定类型的实例方法:

//

Boolean DelegateRefersToInstanceMethodOfType(

MulticastDelegate d, Type type) {


return((d.Target != null) && d.Target.GetType == type);

}

//


你还应该编写代码检查是否回调方法由专门的名字(如FeedbackToMsgBox):

//

Boolean DelegateRefersToMethodOfName(

MulticastDelegate d, String methodName) {


return(d.Method.Name == methodName);

}

//

  现在你知道了如何构造委派对象,下面让我们来谈谈回调方法是如何被调用的。为方便起见,我们还是使用

Set类中的ProcessItems:

//

public void ProcessItems(Feedback feedback) {

for (Int32 item = 1; item <= items.Length; item++) {

if (feedback != null) {

// 如果指定任何回调,则调用它们

feedback(items[item], item, items.Length);

}

}

}

//


   注释行下面的那一行代码就是调用回调方法。仔细看看代码,它调用feedback函数并传递三个参数。但是feedback是不存在的。再一次指出,编译器知道feedback是个引用某个委派对象的变量,并且编译器会产生实际的代码来调用委派对象的Invoke方法。换句话说,编译器看到下面这行代码后:

feedback(items[item], item, items.Length);

编译器产生的结果与下面这行源代码产生的结果一样:

feedback.Invoke(items[item], item, items.Length);
  事实上,通过使用ILDasm.exe程序检查ProcessItems代码结果(如图五),你能发现这一点。



图五 分解后的 Set类的 ProcessItems

   图五显示了用于Set类型中ProcessItems方法的微软中介语言。其中红色的箭头指向的指令调用Set.Feedback的Invoke方法。如果你修改源代码来显式调用Invoke方法,C#编译器报错,出错信息为:“error CS1533: Invoke cannot be called directly on a delegate”——意思是Invoke不能针对某个委派被直接调用。C#不允许你显式调用Invoke(但是,但别的编译器可以)。

   你会想起当编译器定义Feedback类的时候,它也定义了Invoke方法。当Invoke被调用时,它使用私有的_target和_methodPtr域来为特定对象调用希望的方法。注意Invoke方法的签名与委派的签名要完全匹配。也就是说,Feedback委派带三个参数并返回void,那么Invoke方法也必须带三个相同的参数并返回void。

结论

   本文讨论了有关委派的基本概念。根据本文目前所讨论的内容,现在你应该能够创建并使用它们。在后继文章中,我将解释链表中的委派链,以及一些有关MulticastDelegate的附加方法,System.Delegate类型和事件等......。等着我的好消息吧。



睿学电脑专家提醒,希望大家多做研究,争取总结出更多更好的经验。
编程技术录入:admin    责任编辑:admin 
  • 上一篇编程技术: 介绍.NET 中的委派(D elegates)之二…

  • 下一篇编程技术: 用C#访问Hot mail …
  • 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】
    最新热点 最新推荐 相关文章
    介绍.NET 中的委派(D elegat…
    介绍.NET 中的委派(D elegat…
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
     | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 |
    网站版权:睿学电脑技术有限公司 版权所有 ©2007-2009 内容版权:本站所有资料均由网友提示或收集于互联网,其版权归原作者所有,如原作者对本站收录其作品有异义,请及时告知,本站将及时删除。如有其它疑问请与站长联系 站长:睿学
    粤ICP备09133177号