探寻C#事件本质1

我最先在学习C#事件的时候,阅读了许多书籍,但总是不能对事件建立起一个比较清晰的概念,对其内部机制和原理也是似是而非,因为这些书籍在描述事件的时候总是夹杂许多其他不能理解的抽象术语,相信许多初学者都有这样的感觉。

同时,在利用IDE进行GUI编程时,IDE总是在内部帮助我们实现了事件必须的一些代码,我们只需双击对象,编 事件处理函数就行了,而我们常常对内部的工作一无所知,或没有去主动理解这些自动生成的代码。

现在我试着回答学习时遇到的几个问题,这将会有助于你理解到底什么是事件。

如何定义一个事件?

语法:修饰符 event关键字 委托类名 事件名;

比如:public event somedelegatename myeventname;

事件到底是什么类型(引用?值?)

事件其实就是一个特殊的委托。

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

对于这一点,我们也可以从事件的定义中看出,不过就是在定义委托对象时加了event关键字表明这个委托现在叫事件。

何谓事件的订阅(subscribe)?

我们用VS2005建立一个只有一个按钮的winform程序,双击按钮,设计器会在Form1.Designer.cs中自动生成一行代码

this.button1.Click += new System.EventHandler(this.button1_Click);


这就是事件的订阅! 其实就是用事件处理函数this.button1_Click来实例化一个委托System.EventHandler(这个函数与委托拥有同样的签名,为什么需要有同样签名,我理解就是要保证委托与函数的类型一致,这样才能把函数句柄赋给一个委托对象,即所谓的用委托封装方法或C++中把一个方法句柄赋给一个 函数指针),并把这个委托对象赋给事件Click(因这Click其实就是一个委托引用,所以可以这样做,从C++的角度来理解,就是把事件处理函数赋给了一个函数指针变量,这样就可以通过调用这个函数指针以执行事件处理函数)

一句话,订阅事件就是将某个委托对象指向一个具体的方法。

什么是引发事件?

当程序中满足某个条件时调用事件就是引发了事件,为什么可以调用事件呢?因为事件就是一个委托,而委托具有C++中 函数指针的作用,调用委托就是调用委托中封装的 事件处理函数

为什么事件可以被多个对象订阅?

知道了事件实际是一个多播委托后,这个问题不难理解,所谓被多个对象订阅,就是事件被触发后,可以导致多个对象做出反应,也就是多个对象的某个 事件处理函数被调用。为什么会这样呢,因为事件是多播委托,即封装了多个函数的委托,调用这个委托实际上就是在调用被封装的这多个函数。



下面用一个最简单的控制台程序例子来说明事件的运作方式



using System;
namespace 最简单的自定义事件
{/// <summary>/// 事件发送类,即调用事件的类/// </summary>class Class1{public delegate void mydelegate(object sender,EventArgs e); //定义委托public event mydelegate myevent; //定义一个委托类型的事件,即定义一个委托对象public void run(){//死循环,不停测试某个条件是否满足,即所谓的监听while(true){if(Console.ReadLine()=="a"){myevent(this,new EventArgs()); //调用事件}}}}/// <summary>/// 事件接收类,即事件处理的类/// </summary>class Class2{static void Main(string[] args){Class1 c1 = new Class1();c1.myevent+= new Class1.mydelegate(c1_myevent); //将委托对象指向具体的事件处理函数,即所谓的订阅事件c1.run();//运行这个事件,因为此时委托已经指向了具体方法,可以运行了}private static void c1_myevent(object sender, EventArgs e){//事件处理方法Console.WriteLine(" 你触发了事件!");}}
}


对于这个例子,为了加深理解事件的本质,我们可以把事件订阅c1.myevent+= new Class1.mydelegate(c1_myevent); 这句注释掉,即事件没有指向任何具体的方法,编译,不会报错,运行它,如果我们不输入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255647.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#图解教程 第十二章 数组

数组数组定义重要细节数组的类型数组是对象一维数组和矩形数组实例化一维数组或矩形数组访问数组元素初始化数组显式初始化一维数组显式初始化矩形数组快捷语法隐式类型数组综合内容交错数组声明交错数组快捷实例化实例化交错数组比较矩形数组和交错数组foreach语句迭代变量是只…

【数据库学习】——windows、MySQL构建新闻管理系统(控制台版)

学习记录&#xff1a;【Python项目实战】PythonMySQL开发新闻管理系统全集_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Qb4y1b75q?p2&spm_id_frompageDriver 目录 一、项目介绍 1、项目结构 2、系统部分功能提前展示 3、项目流程图 4、项目设计的数据库以及…

matlab张量工具初步

最近从桑迪亚实验室下载了张量工具包。但是不太会用。 很多网上的方法&#xff0c; addpath(pwd) cd met; addpath(pwd) savepath Mones(4,3,2); Xtensor(M); Xtensor(rand(5,1)) Ytensor(rand(4,3,1)) Xtenrand([4 3 2]) X.size %*************************** Rsptenrand([5 4…

微信红包API接口(PHP)

发布时间&#xff1a;2015年2月25日 / 分类&#xff1a;WEB开发,PHP / 74,825 / 241 ℃ 根据微信高级红包接口&#xff0c;开发PHP版本的API接口&#xff0c;现在进行主要代码分析。 红包接口调用请求代码&#xff0c;所有请求参数为必填参数与文档对应&#xff1a; 1234567891…

2016年个人技术总结(前端)

自我总结 参与项目 备注:[☆-表示比较吊的项目,-从头开始做,^-中间加入项目] 神马生活(微信公众号商城)[^] 神马学院[] <!------跳槽线--------> 大数据套件[☆][^] fable数据营销平台(加入新功能&#xff0c;交互)[^] fit问卷系统[] fit投放系统[] fit画像[^] 理财通点击…

浅谈OpenCV[轉]

OpenCV是一个由Interl公司支持的开源机器视觉库&#xff0c;关于它的介绍&#xff0c;网上随便一搜就车载斗量。这里我不谈OpenCV的主要内容&#xff0c;而是将这段时间来对它的使用心得作个简单介绍&#xff0c;以启发打算用这个库的朋友的思路&#xff0c;与大家一起来分享。…

【pyqt5学习】——tablewidget控件学习

目录 1、Table Widget 1.QTableWidget不能在mainwindow中随主窗口的大小变化&#xff1f; 2.将表格变为禁止编辑&#xff1a; 3.设置表格为整行选择 4.单个选中和多个选中的设置&#xff1a; 5.表格表头的显示与隐藏 6.对表头文字的字体、颜色进行设置 7.在单元格里加入…

吴忠军 - 如何理解马云所说的月入两三万,三四万的人最幸福?

这句话源于一段两分钟的视频&#xff0c;马云的一次阿里内部会议演讲。 马云坦承&#xff0c;自己从第一天起就没想过当首富&#xff0c;还为此稀释公司持股&#xff0c;“没想到把自己的股份降到8%&#xff0c;还是有那么多&#xff0c;这是我没有想到的。” 在马云看来&#…

iOS小知识点(非UI部分)

1。 _cmd 表示当前方法的SEL指针&#xff0c; - (void)putString{} 对于这个函数_cmd 等效于selector(putString)转载于:https://www.cnblogs.com/dongfangchun/p/5341599.html

jQuery 操作 CSS

jQuery 拥有若干进行 CSS 操作的方法。我们将学习下面这些&#xff1a; addClass() - 向被选元素添加一个或多个类removeClass() - 从被选元素删除一个或多个类toggleClass() - 对被选元素进行添加/删除类的切换操作css() - 设置或返回样式属性转载于:https://www.cnblogs.com/…

彩色CCD相机工作原理

原理 黑白&#xff08;单色&#xff09;相机 CCD原理并不复杂。我们可以把它想象成一个顶部被打开的记忆芯片。因此光束可以射到记忆单元中。根据"光电效应”&#xff0c;这些光束在记忆单元中产生负电荷&#xff08;下图中右上部分&#xff09;。 曝光后&…

Linux 系统常用命令汇总(二) vi 文本编辑

文本编辑vi命令作用文件名编辑文本文件&#xff0c;若文件不存在同时创建该文件Ctrlf向后翻一页Ctrlb向前翻一页Ctrld向后翻半页Ctrlu向前翻半页光标移动到下一行-光标移动到上一行数字空格光标向右移动n个字符0移动到本行首个字符处$ 移动到本行最后一个字符处H光标移动到屏幕…

图像处理与计算机视觉:基础,经典以及最近发展(2)图像处理与计算机视觉相关的书籍

1. 数学 我们所说的图像处理实际上就是数字图像处理&#xff0c;是把真实世界中的连续三维随机信号投影到传感器的二维平面上&#xff0c;采样并量化后得到二维矩阵。数字图像处理就是二维矩阵的处理&#xff0c;而从二维图像中恢复出三维场景就是计算机视觉的主要任务之一。这…

【HTML学习】——HTML常见标签属性和方法介绍

目录 1、HTML分块--------< div> 2、HTML段落--------< p> 3、HTML标题--------< h1>…< h6> 4、HTML链接--------< a> 1)< a href“http://www.baidu.com”>百度< /a>&#xff08;点击百度&#xff0c;直接跳转到网页&#xf…

开发者应警惕的七种糟糕职业规划错误

那些心灵鸡汤式的说辞总爱美化失败&#xff1a;失败是成功之母啦、失败使人成长啦、别畏惧失败等等。但事实上&#xff0c;这种思路在软件开发领域也许并不适用——至少不完全适用。每位开发者在职业生涯中都不可避免会遭遇失败&#xff0c;但为什么不从他人的经验中汲取教训来…

Splay模板

打LCT的时候发现Splay很不熟, 因此这里贴一下模板 洛谷P3369 https://www.luogu.org/problem/show?pid3369#sub /* 提一些要注意的点: 1. 注意判断边界, 不要访问到空节点 2. 每一次操作或访问完以后, 记得要splay到root 3. insert操作只要update当前节点和父亲节点即可, 因为…

图像处理与计算机视觉 基础、经典以及最近发展

申明&#xff1a;本文非笔者原创&#xff0c;原文转载自&#xff1a;http://blog.csdn.net/liuyue2046/article/details/12658441 ***************************************************************************************************************************************…

【HTML学习】——一个网页HTML编程的构成

目录 1、html网页构成介绍 2、HTML标签介绍 全部的html标签&#xff1a; HTML: HyperText Markup Language | MDNhttps://developer.mozilla.org/en-US/docs/Web/HTML 一个网页文件一般由.html结尾的文件组成&#xff0c;主要由不同的标签对和内容组成&#xff0c;常见的html…

hbase里插入big int数据用Phoenix查看的报错问题

Phoenix建表create table "test_big_int"("ROW" varchar primary key,"ci"."column1" bigint) 在hbase里put数据hbase 里面进行put: put test_big_int,001,ci:column1,1 在Phoenix里进行查看&#xff08;问题出现&#xff09;第二个尝…

机器学习:利用卷积神经网络实现图像风格迁移 (一)

相信很多人都对之前大名鼎鼎的 Prisma 早有耳闻&#xff0c;Prisma 能够将一张普通的图像转换成各种艺术风格的图像&#xff0c;今天&#xff0c;我们将要介绍一下Prisma 这款软件背后的算法原理。就是发表于 2016 CVPR 一篇文章&#xff0c; “ Image Style Transfer Using Co…