`
lovnet
  • 浏览: 6704535 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

C# Event是对Delegate的封装,Delegate类似函数指针

 
阅读更多

由于C#托管代码中是没有指针的,所以当要把一个函数做为一个参数传给另外一个函数时,用正常方法就没办法了,由于就弄出了个代理(Delegate),当然C#中的代理也只是类似函数指针,它除了能实现函数指针的功能外还有其他一些特性.

先来说下C++中的函数指针:

void PrintNum(int num) { cout<<num;} //一个打印数字的简单函数

void (*FunPtr)(int); //声明一个函数指针

FunPtr = PrintNum; //函数指针指向函数PrintNum

//下面几个语句都是等价的

PrintNum(8);

(*PrintNum)(8);

FunPtr(8);

(*FunPtr)(8);

void Fun(int num,void (*FunPtr)(int)) { FunPtr(num);} //函数指针做为参数传给另外一个函数

Fun(8,FunPtr); //调用上面的函数

C# 代理(Delegate)

说完了指针就来说与它类似的Delegate:

void PrintNum(int num) { Console.Write(num);} //一个打印数字的简单函数

delegate void DePrintNum(int num); //声明一个代理,有点类似声明一个指针,在C#中的话有点类似自定义的一个类型

DePrintNum de; //定义一个定理变量

de= PrintNum; //实例化变量de,相当于指针变量指向一个函数,它和语句de = new DePrintNum(PrintNum);是等价的

de(8); //打印数字8,和PrintNum(8)结果相同

void PrintSomething(int num,DePrintNum de) { de(num);} //把代理变量当参数传递,相当于把函数当参数传递

PrintSomething(8,de); //调用上面的函数

上面是代理和函数指针类似的地方,但它还是些另外的特性,比如可以把多个函数绑定到一个代理变量上

假如还有函数void PrintEno(int num) { Console.Write(num + 1);}

de += PrintEno; //de -= PrintNum就是去掉和函数PrintNum的绑定

de(8); //此时相当于同时调用了PrintNum(8)和PrintEno(8);

C# 事件(Event)

我们都知道C#很喜欢按照面向对象的思想来,本来类中随便声明个变量(标准叫法是字段),但还要再弄个属性出来把它再封装下.

那有个代理之后自然也想个法子把它封装下,于是就有个事件(Event):

比如上面有声明了代理

delegate void DePrintNum(int num);

public event DePrintNumePrintNum ; //其实和声明一个代理变量类似DePrintNum de;相当于把de封装了.不过这里没有用到de,类似于直接用属性没有了字段

ePrintNum += PrintNum; //事件里只能用+=,-=了,不能直接来个等号绑定函数了啊.这里自然也可以用+=连续绑定多个函数

ePrintNum(8); //调用事件,这跟代理一样,都相当于是一个函数指针,去间接的调用函数

//补充:事件和代理用起来区别不太大,只是声明的时候不太一样,不过另外还有个比较大的区别:假如ePrintNum是在类Class1中声明的,则像ePrintNum(8)这样的调用只能

在Class1中才是对的,如果在其他类中都不能实例化一个Class1再调用,只能通过+=,-=去给事件绑定或去掉函数,而如果代理的话就可以通过实例化Class1,然后直接调用代理.这或许就是封装性的一个好处了吧.假如不想让另外的类调用你的代理,而只想让它绑定个函数过来,就可以把代理封装成事件了.

补充

在C#中可能碰到事件最多的地方是.net里面自动生成的很多事件,比如点击下鼠标之类的都对就一个事件,不过我们写代码时只要写事件最终绑定的那个函数里的代码就行了.其他的就不用管了.

另外我们知道C#里面没有了全局函数,全局变量,所有的东西都整到了一个个的class中(或者struct中),但是其实我们发现枚举(enum),代理的声明除了放在class中外也可以放在 class外.其实我们把enum看成类似struct,把代理看成类似class就比较好理解了.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics