C#中委托的理解

时间:2021-03-25 19:30:33
1. 如果你学过C语言,那么当你学到C#委托的时候应该比较好理解。因为C#中的委托类型与C语言中的函数指针类型是非常类似的。


2. 先来回顾一下C语言中函数指针的定义。C语言中可以这样来定义一个函数指针类型:typedef void (*pFunc)(int a,char *buf);这里定义了一个返回值为void,参数列表为int,char *的函数指针类型,注意是函数指针类型,而不是函数指针变量。


3. 现在来对比一下C#中委托(注意委托是一种类型)的定义。public delegate void MyDelegate(int a,char[] buf),这样定义了一个委托类型,它具有int,char[]的参数列表和void返回值。注意这里定义的也是一种类型,这就是为什么委托类型的定义不必须放在类内部的原因。


4. 现在再来看两种类型定以后怎么使用:
(1) C语言中定义函数指针类型后,用的最多的情况就是底层定义一个这种类型的变量,上层给这个变量赋值,底层在某种情况下调用这个变量(函数指针,即调用函数)。以下是一个例子:
/* top.c中 */
void func1(void)
{
/* do something */
}


int main(int argc,char** argv)
{
CallBackReg(func1); //将func1赋值给CallBackFunc
while(1)
{
/* do nothing */
}
}


/* base.c中 */
typedef void (*pFunc)(int a,char *buf); //定义一个函数指针类型
static pFunc CallBackFunc = null; //定义一个函数指针变量


void CallBackReg(pFunc func)
{
CallBackFunc = func;
}


void func2(void)
{
if(CallBackFunc!=null)
{
CallBackFunc(); //实际调用的就是func1
}
}
这是C语言中使用函数指针的典型例子,在编程中使用得非常多。这里top.c和base.c是两个模块,在base.c中定义了pFunc函数指针和CallBackFunc指针变量,在top.c中将func1函数指针赋给CallBackFunc变量,这样base.c中通过CallBackFunc();访问到的就是func1这个函数。
有人会问为什么不再func2中直接调用func1函数,我在初学的时候也犯过这样的问题。不这样做的原因是,base.c处于top.c底层时,对base.c来说它并不知道要去调用哪个函数,一般这样的直接调用是上层去调用底层的。而且如果写成直接调用,那么当top.c中func改变或top.c已不存在时,将波及到base.c


(2) C#中委托类型的使用举个事件的例子:
public delegate void MyDel();
/* class1中 */
Class2 class2; //声明Classs的一个实例
void func1()
{
/* do something */
}


static void Main()
{
class2 = new Class2();
class2.my_del += func1; //添加方法
}


/* class2中 */
public event MyDel my_del; //声明一个事件


void func2(void)
{
if(my_del!=null) //声明时自动初始化为null,如果不为null,即有人给它添加了方法
{
my_del();
}



5. 总结:仔细观察体会这两个例子,会发现C#中的委托与C语言中的函数指针类型的相同点。当然C#中委托还有其他一些特性,这里讲到的仅仅是对一种情况的理解。如有不当,烦请指正。
联系QQ:1015043947