zoukankan      html  css  js  c++  java
  • 委托事件小计

    委托提供了安全的方法回调机制。
    常见用法:

    1.winform asp.net 中的按钮事件。
    2.winform中 窗体A弹出窗体B, 点击窗体B的按钮,修改窗体A的属性。
    3.封装流程,通过委托注入,实现了更加轻量级的 模板方法模式的实现。

    首先我们定义一个委托

    public delegate void MyDelegate(string name);
    

    事实上,编译器会将该委托编译为一个类

        public sealed class MyDelegate : MulticastDelegate
        {
            public MyDelegate(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);
        }
    

    该类 主要包含了 一个构造函数,一个invoke方法,以及一对异步invoke方法。

    委托类的 继承层次 为 MyDelegate -> MulticastDelegate -> Delegate

    Delegate中有两个重要的属性 Method 和 Target 

            // 摘要:
            //     获取委托所表示的方法。
            //
            // 返回结果:
            //     描述委托所表示的方法的 System.Reflection.MethodInfo。
            //
            // 异常:
            //   System.MemberAccessException:
            //     调用方不能访问委托所表示的方法(例如,当该方法为私有时)。
            public MethodInfo Method { get; }
            //
            // 摘要:
            //     获取类实例,当前委托将对其调用实例方法。
            //
            // 返回结果:
            //     如果委托表示实例方法,则为当前委托对其调用实例方法的对象;如果委托表示静态方法,则为 null。
            public object Target { get; }
    

    Delegate还定义了一系列的 静态方法。

    委托的写法有以下四种:

            
            void GetName(string name) { }
            MyDelegate myDelegate = new MyDelegate(this.GetName);
            MyDelegate myDelegate2 = this.GetName;
            MyDelegate myDelegate3 = delegate(string a) { this.GetName(a); };
            MyDelegate myDelegate4 = a => this.GetName(a);

    .net中的委托是多播委托,可以将多个委托绑定到一个委托链上,同理也可以删除委托。

                myDelegate += this.GetName;
                myDelegate += myDelegate2;
                myDelegate -= myDelegate3;
    

    可以通过 MulticastDelegate 获取到委托链上的所有委托

            //
            // 摘要:
            //     按照调用顺序返回此多路广播委托的调用列表。
            //
            // 返回结果:
            //     一个委托数组,这些委托的调用列表合起来与此实例的调用列表一致。
            //
            // 异常:
            //   System.MemberAccessException:
            //     无法创建抽象类的实例,或者用后期绑定机制调用了该成员。
            public override sealed Delegate[] GetInvocationList();
    

    该函数返回的是 Delegate[] ,实际使用时需要强制转换为对应的委托类型。

    委托的调用方法
    可以将一个委托变量当做方法直接调用

                myDelegate("YLWS");
               //实际上会调用委托上的Invoke方法
                myDelegate.Invoke("YLWS");
    

    同时,委托提供了一组异步调用的方法

                myDelegate.BeginInvoke("YLWS",
                    a =>
                    {
                        Thread.Sleep(5000);
                        AsyncResult result = (AsyncResult)a;
                        MyDelegate del = (MyDelegate)result.AsyncDelegate;
                        del.EndInvoke(a);
                        string data = a.AsyncState.ToString();//获取到 @objec对象
                        //dosomething
                    },
                    "Test"
                    );

    事件是对委托的封装,对外只提供了 += 和-= 两种操作。最简单的对应就是 属性之于字段。
    属性风格的事件如下:

            public delegate void MyDelegate(string name);
            private MyDelegate nameChanged;
            public event MyDelegate OnNameChanged
            {
                add
                {
                    nameChanged += value;
    
                }
                remove
                {
                    nameChanged -= value;
                }
            }

    参考 委托和事件 从.NET中委托写法的演变谈开去 

    扩展 谈谈.NET中常见的内存泄露问题——GC、委托事件和弱引用

  • 相关阅读:
    html 基本布局介绍
    Hbase1.1.x Java版之批量查删操作
    java命令执行jar文件
    【转】python多版本并存,python3安装pip
    JavaHbase连接代码示例
    Shell执行将脚本里的变量打印到指定日志文件
    Datax将本地文件导入Hbase数据库!!!酷酷酷
    shell关于日期的加减
    python2安装pymongo
    Python从MongoDB中按天读取数据并格式化日志
  • 原文地址:https://www.cnblogs.com/ylws/p/3200122.html
Copyright © 2011-2022 走看看