记自己理解的委托与事件

关于委托与事件的文章,一抓一大把。那我为什么还要重复造轮子呢?-----理由很简单,别人的文章是他们理解的,而不是自己所理解的,读他们的文章时,或多或少缺少一些东西。所以在此仅记自己理解的委托与事件。

一、为什么要引入(使用委托)

委托相当于方法指针,调用委托相当于触发委托中的方法。很多书籍都以对不同人以不同语言的问候作为例子,提出将方法参数化,然后再在真正的调用者中调用该方法,从而引入了委托。每当看到这种形式的时候,我总是觉得那里不对,看了半天没弄明白。直到某天,某大牛说,委托呢,从字面去理解就好了,委托就是委托第三方去帮你办某件事情,这个地方不仅可以接受你的委托,也可以接受别人的委托,从而可以进行统一的处理。这才有所理解。在使用不少次委托之后,个人觉得引入委托是可以将方法参数化,但更多的是委托可以接受多个委托的方法(符合委托定义要求的方法),实现统一处理。(常用:类之间传递参数,例如子窗体传递参数至父窗体;委托链:同时触发多个方法)。

二、委托与接口之间的区别:

接口定义了行为规范,其行为规范可以是多个的(规定多个方法、事件、属性、索引器);委托也是一种规范,委托的方法必须是同类型返回值,同类型参数的方法,但它只能定义单个的。接口的多态与委托的多播类似。

三、为什么要引入事件

事件是定义好的委托链,它只能在类的内部定义,在类的内部进行传递给其他事件(在定义其的类的内部,它可以出现在“+=”的右边实现传递),在类的外部只能是出现在“+=”或者“-=”的左边,而单纯的委托是可以的(这里只说“+=”、“-=”、“=”三种情况,如触发、判断是否为空不算)。所以事件是实现了对委托的封装。

四、为什么一般的委托不带返回值,带返回值的如何处理不同方法的返回值

因为委托实现多播,同时包含多个方法时,简单的委托触发,最终只能得到最后调用的方法的返回值,之前的则丢失,此时返回值则没太大的意义了。

五、委托异步调用

BeginInvoke..EndInvoke...很多时候在处理较长时长的业务时,将启动线程或者使用异步的方式进行处理。

 

零碎的学习Demo:

事件属性

        private event WarnHandler mWarn;
        public event WarnHandler MWarn
        {
            add
            {
               // mWarn = value;  //决定事件只能绑定一个方法
                mWarn += value; //事件可绑定多个方法
            }
            remove
            {
                mWarn -= value;
            }
        }

  简单调用

 GreedHanlder TGreed;
        event GreedHanlder TGreedEvent;
        public void Test()
        {

            Person p1 = new Person() { Name = "Tim", Language = "English" };
            Person p2 = new Person() { Name = "张三", Language = "Chinese" };
            ProxyPerson proxyPerson = new ProxyPerson();
            proxyPerson.MGreed += p1.Greed;
            proxyPerson.MGreed += p2.Greed;
            proxyPerson.Greeding("xx");
            proxyPerson.MGreed = TGreed; //单纯的代理可以在外部类重新赋值,相当于重新定义
            proxyPerson.GreedEvent += TGreedEvent;
            p1.EGreed = p2.EGreed;
            // proxyPerson.GreedEvent += p1.PGreed;//(不同通过)事件只能是本身类的事件加入到其他类的事件中,不能将其他类的事件相互添加


        }

  

   public void OnGreed(string name)
        {
            if (GreedEvent != null)
            {
                GreedEvent(name);
            }

        }
        /// <summary>
        /// 逐个调用
        /// 逐个调用,可以获取不同方法的返回值,但是意义不大
        /// </summary>
        /// <param name="name"></param>
        public void OnGreedInner(string name)
        {
            Delegate[] delegates = MGreed.GetInvocationList();
            foreach (var item in delegates)
            {
                GreedHanlder greed = (GreedHanlder)item;
                if (greed != null)
                {
                    greed(name);
                }
            }
        }

  

异步

 public delegate IList<object> QueryHandler(string name);
    public class ObjBo
    {
        public event QueryHandler Query;
        public void Test(string name)
        {
            if (Query != null)
            {
                Query.BeginInvoke(name,new AsyncCallback(BindData),null);
            }
        }
        public void BindData(IAsyncResult a)
        {
            AsyncResult asyncResult = a as AsyncResult;
            string str = asyncResult.AsyncState.ToString();
            QueryHandler query = (QueryHandler)asyncResult.AsyncDelegate;
           IList<object> objs= query.EndInvoke(a);
            
        }
    }

  

Top
收藏
关注
评论
原文地址:https://www.cnblogs.com/Joy-et/p/4357909.html