C#中的委托和事件(4)

作者:JimmyZiYang 来源:蓝色理想 时间:2007-09-26 20:50:00 

事件和委托的编译代码

这时候,我们不得不注释掉编译错误的行,然后重新进行编译,再借助Reflactor来对 event的声明语句做一探究,看看为什么会发生这样的错误:


public event GreetingDelegate MakeGreet;


可以看到,实际上尽管我们在GreetingManager里将 MakeGreet 声明为public,但是,实际上MakeGreet会被编译成 私有字段,难怪会发生上面的编译错误了,因为它根本就不允许在GreetingManager类的外面以赋值的方式访问。

我们进一步看下MakeGreet所产生的代码:


private GreetingDelegate MakeGreet;       //对事件的声明 实际是 声明一个私有的委托变量

[MethodImpl(MethodImplOptions.Synchronized)]
public void add_MakeGreet(GreetingDelegate value){
    this.MakeGreet = (GreetingDelegate) Delegate.Combine(this.MakeGreet, value);
}

[MethodImpl(MethodImplOptions.Synchronized)]
public void remove_MakeGreet(GreetingDelegate value){
    this.MakeGreet = (GreetingDelegate) Delegate.Remove(this.MakeGreet, value);
}


现在已经很明确了:MakeGreet 事件确实是一个GreetingDelegate类型的委托,只不过不管是不是声明为public,它总是被声明为private。另外,它还有两个方法,分别是add_MakeGreet和remove_MakeGreet,这两个方法分别用于注册委托类型的方法和取消注册,实际上也就是: “+= ”对应 add_MakeGreet,“-=”对应remove_MakeGreet。而这两个方法的访问限制取决于声明事件时的访问限制符。

在add_MakeGreet()方法内部,实际上调用了System.Delegate的Combine()静态方法,这个方法用于将当前的变量添加到委托链表中。我们前面提到过两次,说委托实际上是一个类,在我们定义委托的时候:


public delegate void GreetingDelegate(string name);


当编译器遇到这段代码的时候,会生成下面这样一个完整的类:


public class GreetingDelegate:System.MulticastDelegate{

       public GreetingDelegate(object @object, IntPtr method);
       public virtual IAsyncResult BeginInvoke(string name, AsyncCallback callback, object @object);
       public virtual void EndInvoke(IAsyncResult result);
       public virtual void Invoke(string name);

}


关于这个类的更深入内容,可以参阅《CLR Via C#》等相关书籍,这里就不再讨论了。

标签:c#,委托,事件
0
投稿

猜你喜欢

  • 浅谈Python2、Python3相对路径、绝对路径导入方法

    2023-07-30 04:09:35
  • Mysql Explain命令的使用与分析

    2024-01-29 08:39:04
  • PHP常用函数之获取汉字首字母功能示例

    2023-06-16 12:24:39
  • PHP中error_reporting()函数的用法(修改PHP屏蔽错误)

    2023-11-20 01:08:17
  • J2EE基础应用:J2EE中SQL语句自动构造方法

    2009-09-18 09:06:00
  • Python存储读取HDF5文件代码解析

    2021-07-24 22:33:09
  • 1 行 Python 代码快速实现 FTP 服务器

    2022-02-19 18:17:41
  • Pythonic版二分查找实现过程原理解析

    2022-01-20 18:01:39
  • javascript基础之indexOf函数

    2008-06-25 13:28:00
  • django实现更改数据库某个字段以及字段段内数据

    2024-01-26 14:52:09
  • SQL Server 分页查询通用存储过程(只做分页查询用)

    2024-01-12 20:10:11
  • MySql完整卸载的四个步骤详解

    2024-01-18 00:30:52
  • python实现学生管理系统

    2022-12-18 02:42:22
  • 解决python3 整数数组转bytes的效率问题

    2023-08-09 19:39:41
  • Mysql联合查询UNION和Order by同时使用报错问题的解决办法

    2024-01-12 18:44:35
  • php 中phar包的使用教程详解

    2024-03-16 15:38:48
  • css+js实现部分区域高亮可编辑遮罩层

    2024-02-25 08:49:23
  • python中range()与xrange()用法分析

    2021-03-23 00:31:30
  • 更新升级python和pip版本后不生效的问题解决

    2022-09-30 18:23:14
  • asp 删除数据并同时删除图片的代码

    2011-02-28 10:39:00
  • asp之家 网络编程 m.aspxhome.com