对委托内部机制的研究

来源:互联网 发布:网络电影分账方案 编辑:程序博客网 时间:2024/06/05 16:55

之前我对委托的认识,只是停留在简单的定义委托,实例化委托,绑定方法等基本操作。

  随着现在对.net的深入学习(尤其在了解.net中的反射机制后),慢慢的对委托的内部运行机制也有了一定的了

解。把它写在我的博客上,一方面能与同行交流,同时也当做是对自己掌握的知识的一种归纳总结。

  切入正题。

  首先要明白的是,Delegate实质是一个类(很废话,不要骂我)。我们在实际运用当中,就是创造一个继承它的

委托类。在使用这个委托的时候,就是调用它继承于父类(即Delegate类)的方法来实现。这里我们主要是要了解

它的两个构造函数和两个属性以及一个Invoke方法。

  先看两个构造函数:

    protected Delegate(Type target,String method); 

    
protected Delegate(object target,String method);

  

  第一个构造函数是当绑定的方法为静态方法时用的,这里我们以第二种,当绑定非静态方法时所用的构造函数为

例来讲解。target是表示绑定方法所在的类的实例(如果是静态方法,则调用第一个构造函数,target参数就是表示

  

方法所在的类),method就是所绑定方法的方法名。这与我们平时初始化委托所用的构造函数不同,平时我们只

  

要传入一个完整的方法名做为参数即可。这是因为上面的这两种构造函数都是不会直接用到的。当我们传入要绑定

  

的方法名时,.Net会自动根据传入的方法名来调动相应的构造函数,并且成生构函数的两个参数。

   

  举个例子:一个名为testDelegate的委托,绑定了Num对象中的一个Add方法。代码段如下:

        

Delegate int testDelegate(int num1,int num2);

public  class Number
...{
    
public Number()
    ...
    
    }

    
public int Add(int num1,int num2)
    ...{
        
return num1 + num2;
    }
}

Number Num = 
new Number();

testDelegate = 
new testDelegate(Num.Add);

  

  这时.Net会分析传入的参数Num.Add,判断它是一个非静态方法,调动第二个构造函数。然后再分析,得知该方

  

法是属于Num对象的,就将Num对象做为target参数;同样的,再将方法名"Add"(是个String类型数据)做method

    

参数。

  

   构造函数就讲到这。下面来看Delegate类的两个属性。

  

     //这个就是传入的target参数
     public object Target ...get; }   

     
//这个是依据传入的method参数生成的对应绑定方法的MethodInfo类的对象。原理应该是利用反射机制。
     public MethodInfo Method ...get; };  

  

  这里补充一下Method属性的获取方法,如下:

  

//target表示方法所在的对象或类,就是第一个参数
System.Type t = target.GetType();  

//method就是传入的方法名,GetMethod()方法就是通过方法名来返回所对应方法的MethodInfo对象
MethodInfo Method = t.GetMethod(method);  

  

  

  太晚了,明天继续写。

  

###################################################################################

  

  继续写。

  

  昨天写到Delegate的两个属性,今天接着写它的最重要的Invoke方法。

  

  Invoke方法,其实是上文中说到的Method属性的一个方法。MethodMethodInfo类的一个实例,MSDN上对它的

  

解释是:发现方法的属性 (Attribute) 并提供对方法元数据的访问。Method.Invoke(),就是对Method所表示的方法的

  

调用。它有两个参数,Object obj Object[] parameters

  obj表示方法所处在的实例象,就是对应之前上面所讲的Target属性。如果方法是静态方法,则忽略这个参数,用

Null做为参数值。

  

   parameters表示方法的签名,即参数。我们要将原方法的参数类型转化成Object []类型,比如上文中的Num.Add

方法有两个int类型的参数num1,num2,则可以这转换:

   

int num1 = 1;
int num2 = 2;

Object [] o = ...{num1,num2};

  PS:刚知道代码可以以这样的形式插入,真是方便)

  所以,我们平时调用的委托方法:

 testDelegate(); 

  就是通过调用:

        testDelegate.Method.Invoke(Target,o);

  来实现的。

  到这里差不多我了解的原理都讲完了。头一次写这么多字的技术文章,真是累啊。

原创粉丝点击