Mcad学习笔记之委托再理解(delegate的构造器,MulticastDelegate,BeginInvoke,EndInvoke,Invoke4个方法的探讨)

相关文章导航
  1. Sql Server2005 Transact-SQL 新兵器学习总结之-总结
  2. Flex,Fms3相关文章索引
  3. FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统((Flex,Fms3联合开发))<视频聊天,会议开发实例8>

 

 

先定义一个委托如下:
public delegate void myEventHandler(int i,out string o);

再用MSIL反汇编程序(Ildasm.exe)来观看反汇编代码
其实CLR为我们做了4件事情
1.定义一个构造器
2.定义一个虚方法BeginInvoke
3.定义一个虚方法EndInvoke
4.定义一个虚方法Invoke

(1)在反汇编代码中我看到如下片断:
.class auto ansi sealed nested public myEventHandler
       extends [mscorlib]System.MulticastDelegate
{
} // end of class myEventHandler
由此可以知道其实我们声明的委托myEventHandler就是一个密封类
它的父类是System.MulticastDelegate
看到这里,我的一个疑惑被解除了
以前我也自己定义过委托,总是感觉好像在程序中到处都可以定义委托,在类里面和类的外部都可以定义,一直不知道为什么?
现在我基本明白了,其实委托是一个类,类可以在哪里定义,委托就可以在哪里定义。

(2)我们现在再来看看构造器
在这之前,有必要搞清楚委托的继承关系
System.Delegate
---System.MulticastDelegate
------ConsoleApplication1.myEventHandler

现在我们实例化一个委托:
myEventHandler my=new myEventHandler(staticCall);
实际上它是在调用这个委托的构造器

下面的是这个构造器的代码:
public myEventHandler(object @object, IntPtr method);
第一个参数应该是类实例的实例
第二个参数应该是委托的方法信息

这个构造器会再调用它父类的构造器,父类构造器代码如下:
protected MulticastDelegate(object target, string method) : base(target, method)
{
}
最终调用的是System.Delegate的构造器
protected Delegate(object target, string method)
这个构造器是对类System.Delegate的2个私有字段进行处理
private object _target;
private RuntimeMethodInfo _method;

System.Delegate类有2个公有属性可以得到上述2个私有字段的数值:
1.Method
获取委托所表示的方法
2.Target
获取类实例,当前委托将对其调用实例方法
如果是静态方法,则为空引用


费话少说,我们来段代码看看效果
建立一个我最爱的控制台程序,代码如下:

 1using System;
 2using System.Reflection;
 3
 4namespace ConsoleApplication1
 5{
 6    class Class1
 7    {
 8        public delegate void myEventHandler(int i,out string o);
 9        /// <summary>
10        /// 应用程序的主入口点。
11        /// </summary>

12        [STAThread]
13        static void Main(string[] args)
14        {
15            Class1 c=new Class1();
16            myEventHandler my=new myEventHandler(staticCall);
17
18            if (my.Target==null)
19            {
20                Console.WriteLine("我们调用的类静态方法");
21            }

22            else
23            {
24                Console.WriteLine("我们调用的类实例名称为:"+my.Target.ToString());
25            }

26            
27            MemberInfo info=my.Method;
28            
29            Console.WriteLine("此方法的基本信息:"+ my.Method.ToString() );
30            Console.WriteLine( my.Method.IsStatic?"此方法是一个静态方法":"此方法是一个实例方法" );
31            Console.WriteLine( "此方法的名称为:"+info.Name );
32
33            Console.ReadLine();
34        }

35
36        public void call(int i,out string o)
37        {
38            o="haha";
39        }

40
41        
42        public static void staticCall(int i,out string o)
43        {
44            o="haha";
45        }

46    }

47}

48

我们可以看到结果


要是把代码中16行替换为
myEventHandler my=new myEventHandler(c.call);
我们可以看到结果



(3)再来看看委托的虚方法BeginInvoke和虚方法EndInvoke
它的代码原型如下:
public virtual IAsyncResult BeginInvoke(int i, out string o, AsyncCallback callback, object @object);
public virtual void EndInvoke(out string o, IAsyncResult result);

BeginInvoke 异步方法签名的规则是:
包括所有 IN 参数。
包括所有 OUT 参数。
包括所有 IN/OUT 参数。
包括所有 ByRef 参数。
将 AsyncCallback 和 AsyncState(可通过 IAsyncResult 接口的 AsyncState 属性获得)作为最后两个参数。
返回 IAsyncResult

EndInvoke 异步方法签名的规则是:
包括所有 IN/OUT 参数。
包括所有 OUT 参数。
包括所有 ByRef 参数。
将 IAsyncResult 作为最后一个参数。

这2个方法提供了委托的异步编程方法支持。


(4)再来看看委托的方法Invoke
它的签名和委托的签名是一样的,实际上是委托的同步编程方法.
实际上是通过它来回调我们委托的方法。

我知道在异步编程中,我们可以利用委托实例直接调用BeginInvoke和EndInvoke方法
那为什么在同步编成中,VS2003不允许我们直接在程序中调用Invoke方法?
一直没明白这个问题,WHY?
vs2005可以允许我们直接在程序中调用Invoke方法

 

关于这4个方法的详细应用可以看这篇文章



还有一个疑问:
我用Reflector(版本是4.1)看到的Invoke方法如下:
public override void Invoke(int i, out string o);
它是一个重写的方法

而我用ildasm.exe看到Invoke方法却是virtual的

其实我更相信后者
因为我查看了myEventHandler的父类中好像没有定义Invoke方法

不知道,大家有什么看法?
 

author:aierong

blog:http://www.cnblogs.com/aierong

http://aierong.cnblogs.com


Sql Server2005 Transact-SQL 新兵器学习总结之-总结
MS SQL数据库备份和恢复存储过程(加强版本)
sql server中分布式查询随笔(链接服务器(sp_addlinkedserver)和远程登录映射(sp_addlinkedsrvlogin)使用小总结)
ASP.NET2.0国际化/本地化应用程序的实现总结(多语言,多文化页面的实现)
WAP开发资料站(最新更新)
自定义格式字符串随笔 (IFormattable,IFormatProvider,ICustomFormatter三接口的实现)
Mcad学习笔记之异步编程(AsyncCallback 委托,IAsyncResult接口,BeginInvoke方法,EndInvoke方法的使用小总结)
Mcad学习笔记之通过反射调用類的方法,屬性,字段,索引器(2種方法)
Mcad学习笔记之序列化(2进制和Soap序列化)
Mcad学习笔记之委托再理解(delegate的构造器,BeginInvoke,EndInvoke,Invoke4个方法的探讨)
WinForm开发,窗体显示和窗体传值相关知识总结
Mcad学习笔记之Microsoft Windows服务
copy某目錄下的所有的目錄和文件到目的目錄(目錄數據備份)
ASP.NET状态管理之一(概括篇)

 

收藏与分享

收藏到QQ书签 添加到百度搜藏 添加到百度搜藏 添加到雅虎收藏 分享到饭否 收藏到就喜欢网络收藏夹

RSS订阅我 什么是RSS?

feedsky    http://wap.feedsky.com/aierongrss    E-mail
订阅到雅蛙       使用RSS邮天下订阅    订阅到有道阅读
订阅到抓虾    鲜果阅读器订阅图标    Add to Google
訂閱 Bloglines    哪吒提醒    Subscribe in NewsGator Online

东莞.net俱乐部

东莞.net俱乐部 欢迎您的加入

posted @ 2005-05-25 14:39  aierong  阅读(12124)  评论(13编辑  收藏  举报