delegate和event的区别

  一. delegate

    C#代理实际上类似于C++中的函数指针,因为C#中不存在指针,所以用代理可以完成一些原来在C++中用函数指针完成的操作,例如传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。但与函数指针相比,delegate有许多函数指针不具备的优点。首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。

    通过以下3个步骤即可实现一个delegate

1 声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。

    声明一个代理的例子:

    public delegate int MyDelegate(string message);

2 创建delegate对象,并将你想要传递的函数作为参数传入。

     创建代理对象的方法:

    1). MyDelegate myDelegate = new MyDelegate(实例名.方法名);

    2). MyDelegate myDelegate = new MyDelegate(类名.方法名);

注:如果需要代理的方法是一个static静态方法的话,采用第2种方式,否则采用第1种方式。

3 在要实现异步调用的地方,通过上一步创建的对象来调用方法。

    可以直接使用代理调用代理所指向的方法:

    myDelegate(向方法传递的参数);

    下面是一些需要注意的事情:

“代理”(delegate)(代表、委托):“代理”是类型安全的并且完全面向对象的。

1)在C#中,所有的代理都是从System.Delegate类派生的(delegateSystem.Delegate的别名)。

2)代理隐含具有sealed属性,即不能用来派生新的类型。

3)代理最大的作用就是为类的事件绑定事件处理程序。

4)在通过代理调用函数前,必须先检查代理是否为空(null),若非空,才能调用函数。(5)在代理实例中可以封装静态的方法也可以封装实例方法。

6)在创建代理实例时,需要传递将要映射的方法或其他代理实例以指明代理将要封装的函数原型(.NET中称为方法签名:signature)。注意,如果映射的是静态方法,传递的参数应该是类名.方法名,如果映射的是实例方法,传递的参数应该是实例名.方法名。

7)只有当两个代理实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。

8)多个代理实例可以形成一个代理链,System.Delegate中的定义了用来维护代理链的静态方法CombionRemove,分别向代理链中添加代理实例和删除代理实例。

9)代理的定义必须放在任何类的外面,如delegate int MyDelegate();而在类的方法中调用MyDelegate d = new MyDelegate(MyClass.MyMethod);来实例化自定义代理的实例。

10)代理三步曲:

a.生成自定义代理类:delegate int MyDelegate();

b.然后实例化代理类:MyDelegate d = new MyDelegate(MyClass.MyMethod);

c.最后通过实例对象调用方法:int ret = d();

  

二:event

 例1

事件是特殊类型的多路广播委托,仅可从声明它们的类或结构(发行者类)中调用。如果其他类或结构订阅了该事件,则当发行者类引发该事件时,会调用其事件处理程序方法。

可以看出,C#中的event是通过delegate实现的,event 只是在delegate基础上作了两点限制:
1:客户只能使用委托所提供的+=和-=行为,不能直接用=,即不影响委托对其他observer的notify.
2:只有声明类可以调用(或激发)一个事件,外部类不可以直接调用其事件。
在一个C#接口中可以包容方法、C#属性以及索引器,也可以包容事件,但不能包含委托,因为接口定义的是成员,委托定义的是一个类型,而事件同样是成员。

 

例 1:

 

例 2:

 

例 3:

 

例 4:

 

 

转载 …… 由本人整理……

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值