之前我对委托的认识,只是停留在简单的定义委托,实例化委托,绑定方法等基本操作。
随着现在对.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属性的一个方法。Method是MethodInfo类的一个实例,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);
来实现的。
到这里差不多我了解的原理都讲完了。头一次写这么多字的技术文章,真是累啊。