Fork me on GitHub

.NET简谈事件与委托

其实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执行委托和事件处理过程是不一样的;事件就事件;

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

posted @ 2011-05-04 14:01  王清培  阅读(1531)  评论(0编辑  收藏  举报