开发者社区> 王清培> 正文

.NET简谈事件与委托

简介: 其实C#的事件与委托在日常开发过程中不用也能解决问题,但是用于不用是不同的;更能体现出对象的高内聚、低耦合,两个对象要想互操作,对外提供接口;甚至是让另一个对象来处理本对象在发生指定事件的时候的操作;打个比方,我把自己比喻成一个对象,把饭店老板比喻成另一个对象;这两个对象是完全独立的,我并不知道我要...
+关注继续查看

其实C#的事件与委托在日常开发过程中不用也能解决问题,但是用于不用是不同的;更能体现出对象的高内聚、低耦合,两个对象要想互操作,对外提供接口;甚至是让另一个对象来处理本对象在发生指定事件的时候的操作;打个比方,我把自己比喻成一个对象,把饭店老板比喻成另一个对象;这两个对象是完全独立的,我并不知道我要到哪家饭店吃饭,而同样饭店老板也不知道谁会来吃饭;如果不存在事件,我到了一家饭店,我跟老板讲我要吃饭,老板不回话,我说我要吃白菜.....等等;都是我自己在操作过程,这样太死板了,我不知道这家饭店是否有我点的菜没有回馈信息;正常的吃饭应该是我到饭店了,老板自己触发了一个事件,事件是他看到有顾客来吃饭了,主动来问我几个人吃饭,吃些什么;而不是我来到一个“真空”饭店;事件是一种传递信息的过程,C#本身是一种面向对象语言,我们要以大自然的规律来思考编程的问题;如果不用事件的话也能实现上述讲的吃饭的问题,这样即繁琐也麻烦不符合面向对象的思想,你来到饭店,然后调用老板的方法:

public bool 吃饭(菜名,数量);//老板提供的方法

if(老板.吃饭(牛肉,10)){这家有牛肉;}//我调用老板的吃饭方法,确定是否有我要的菜;

这样的话,不管谁来吃饭你都要提供一种方法,来供外部调用;每个人都吃饭习惯,点菜习惯不同对数量的理解更是不能很透彻的明白,这样就产生了一个问题,互动性很差,没有沟通,没有回应;如果有了事件,显然就变的更人性化一点,对外不需要考虑太多,本店的特色定义成过程事件,特色的步骤必须是这样的,将本饭店的特色定义成一个个的过程事件,顾客来了按照这样的一个事件流程执行,就很准确的知道顾客要吃些什么,事件是一个很好的互相沟通渠道;来人了先问吃什么口味,这是一个事件如果客户说我不吃就不操作这个事件,老板的事件参数也没有接收到任何客户输入的信息;下面我就以吃饭为例子讲解对象的事件;

public  class 老板

{

    public delegate void 看见有顾客来了(string 问好);事件的委托,后面讲到;

    public Event 看见有顾客来了 顾客来吃饭;//顾客来了吃饭,这是一个事件;

    public void On顾客来吃饭(string info);//引发事件的方法;

}

public  class 顾客

{

    老板 laoban=new 老板();

    laoban.顾客来吃饭+=new 看见有顾客来了(处理老板事件);

    public void 处理老板事件(string 问好)

    {

      Messagebox.show("您好,有牛肉吗?");
    }

    laoban.On顾客来吃饭("您好请问吃些什么");//这个方法也许在某个事件触发后调用的,一般不在订阅对象中触发;

}

我简单的实现订阅老板的事件,然后老板问好吃什么,我回馈有牛肉吗,这是比喻而已也许有点不恰当;下面深入理解委托与事件的关系;

委托字面理解就是帮忙做事的,中间方的意思,在代码中的意思就是说,用委托来关联方法与事件的;当触发事件了,通过委托链来一个一个调用绑定在委托链上的所有实体方法,委托链:

看过数据结构的同志都知道链表的结构,每一个数据域都是存放调用着的方法如:

laoban.顾客来吃饭+=new 看见有顾客来了(处理老板事件1);//这样就是将一个方法绑定到委托链的一个数据域中了;

laoban.顾客来吃饭+=new 看见有顾客来了(处理老板事件2);//可以连续绑定多个方法到一个委托链上,实现多播委托;

在上述这幅图中,绑定了四个方法到委托链上,当调用委托链的方法时,委托链会按照当初绑定的顺序调用委托链上的方法,先调用

“处理老板事件1方法”,“然后调用处理老板事件2”;委托链的调用参数是向下传递的,就是在调用第一个方法得出的结果会继续向下传递到第二个方法,如果在方法执行的过程中没有对出入的参数进行修改,参数就不会受到影响,这是针对引用类型而言的;

事件字面理解就是会被触发的动作过程,比如人,你跟我说一句话我耳朵就接收到了,然后我内部进行处理,确定触发什么事件;委托是委托事件是事件,两者是没有关系的,只不过事件利用委托的特点来帮忙处理一下事件的方法而已;在我们使用委托的时候要先确定这个委托的类型,什么叫类型就是确定代码的物理结构,定义委托:

delegate void delegatename();//delegate是委托的关键字,delegatename是委托的名称,定义委托的类型就是确定委托链中的数据域存放的数据结构类型,在我们学习数据结构的时候要先定义没一个节点的数据类型,道理差不多;确定了类型之后就是具体的实例了:

Event delegatename Eventname;用事件关键字和委托类型定义事件实例,其实事件实例就是委托实例,每一个对象存在都有意义表面看来用委托一样能实现对方法的连续的调用,为什么还要事件呢,有些东西不是表面看起来那么简单的,事件的存在是关联物理结构的,当CLR执行委托和事件处理过程是不一样的;事件就事件;

事件与委托就讲到这里了,希望能帮助你进一步理解,上面都是本人自己的理解,如有错误的地方还请高人指点谢谢

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
[转]ASP.NET 页面事件执行顺序
在作完上图后,无意中看到网上类似的一篇文章,也非常精彩,转载在下面供大家参考。申明,以下内容为转载,因某些原因作者和出处无法考证,本文作者不享有以下内容的版权。 Page 执行中将按照如下顺序激活事件: Page.
720 0
.NET Core工程编译事件$(TargetDir)变量为空引发的思考
前言 最近客户反馈,为啥不用xcopy命令代替我自己写的命令来完成插件编译复制: 我的: call "$(SolutionDir)tools\tools\Magicodes.CmdTools.
1153 0
一起谈.NET技术,C# 委托,事件和Lambda表达式
  关于这个论题,Delegates, Events, and Lambda Expressions 对此有比较深入的分析,可以参考。C# vs C++之一:委托 vs 函数指针 比较了委托和C++指针的区别。
868 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
29209 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
20721 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
23589 0
.Net中模拟上传文件动态显示进度的事件示例
    public class UploadEventArgs : EventArgs//作为事件的参数,必须派生自EventArgs基类     {         public UploadEventArgs(int percent)         {             this.
654 0
asp.net页面事件执行顺序(转)
#region OnPreInit 第一步    protected override void OnPreInit(EventArgs e)    {        //检查 IsPostBack 属性来确定是不是第一次处理该页。
727 0
+关注
王清培
趣头条 Tech Leader
138
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载