• 委托和事件


    一、委托:是一个能够引用方法的对象。创建委托时实际是创建一个方法引用的对象,创建的引用对象能够调用方法。

      委托调用可以调用不同的方法,只需改变方法的引用即可。即委托调用方法是运行时确定,而非编译时确定。

      就像声名一个object实例一样,声名的只是一个占位符,具体指向哪个对象在运行时可以动态指定。在委托中指定方法有限制:返回值,参数类型要相同。

      

      委托声名:delegate ret-type delegatename(parameter-list)

      delegate 关键字声名委托

      ret-type是委托返回值类型

      delegatename 委托名称

      parameter-list 参数列表

      委托声名的是一个方法引用对象,被委托引用的方法返回值类型、形参类型必须与委托定义的相同,不限制是静态方法、还是实例方法。

      

      委托示例:  

       //委托使用静态方法声名
                StrMethodDelegate strdelegate = new StrMethodDelegate(StaticMethodClass.StaticStrMethod);
                //调用方法
                string result = strdelegate("HI");
                Console.WriteLine(result);
    
                //委托使用实例方法声名
                InstanceClass instanceClass = new InstanceClass();
                StrMethodDelegate instanceDelegate = new StrMethodDelegate(instanceClass.InstanceStrMethod);
                result = instanceDelegate("Hi");
    View Code

      运行结果:

      

       

     委托方法组转换:允许简单的为委托指定方法名称,不再使用new或者显示的调用构造函数。实际操作就像是变量赋值一样把方法赋值给方法引用。

      委托方法转换示例:  

                VoidMethodDeleteage voidDelegateone = StaticMethodClass.FirstStaticEmpMethod;
                voidDelegateone();
                VoidMethodDeleteage voidDelegatetwo = new InstanceClass().FirstInstanceEmpMethod;
                voidDelegatetwo();
    View Code

       运行结果:

      

      委托多播:多播是指委托有创建方法调用列表,方法调用链表的能力。通过+、+=、-、-=运算符为链表添加方法。

      示例代码:  

        VoidMethodDeleteage multi =             StaticMethodClass.FirstStaticEmpMethod;
                multi += StaticMethodClass.SecondStaticEmpMethod;
    
                InstanceClass incclass = new InstanceClass();
    
                multi += incclass.FirstInstanceEmpMethod;
    
                multi();
    
                multi -= incclass.FirstInstanceEmpMethod;
    
                multi();    
    View Code

      运行结果:

      

      匿名方法赋值给委托

      使用delegate关键字创建匿名方法,可以赋值给委托。  

    VoidMethodDeleteage delte = delegate
                {
                    for (int i = 0; i <= 5; i++)
                    {
                        Console.Write(i);
                        Console.Write(" ");
                    }
                };
    
                delte();
    View Code

      运行结果:

      

      Lambda赋值给委托  

     StrMethodDelegate delegateInc = n =>
                {
                    return "Lambda ReturnValue:" + n;
                };
    
                string returnstr = delegateInc("Hello");
                Console.WriteLine(returnstr);
    View Code

      运行结果:

      

      使用匿名函数和lambad表达式和实例方法、静态方法一样能够进行方法的调用。 

      协变、逆变

      协变是指:只要方法的返回值类型派于委托声明的返回类型,该方法就可赋值给委托。

      逆变是指:只要方法参数的类型是委托声明类的父类,该方法即可赋值给委托。

      

    二、事件:事件是基于委托类型,事件是一种信号机制,通知应用程序操作发生。

      工作原理是:如果对象对某事件感兴趣,则对象为事件注册事件的处理程序,事件发生时就会调用注册在事件上的处理程序。

      

      事件声明:使用Event关键字声明事件。

      Event event-delegate event-name

      Event声明事件关键字

      event-delegate 支持事件的委托声明,意思事件的注册程序通过委托来承载。

      event-name 具体的事件对象的名称。

      事件示例:  

    delegate void MyEventHandle();
     static void Main(string[] args)
            {
                EventDemo demo = new EventDemo();
                //注册事件
                demo.SomeEvent += Handler;
                //事件发生
                demo.OnSomeEvent();
                Console.ReadKey();
            }
    
            public static void Handler()
            {
                Console.WriteLine("Event ocurred");
            }
        class EventDemo
        {
            public event MyEventHandle SomeEvent;
    
            //触发事件
            public void OnSomeEvent()
            {
                if (SomeEvent != null)
                {
                    SomeEvent();
                }
            }
        }
    View Code

      运行结果:

      

      

      事件多播

      事件是基于委托创建,所以事件是支持事件多播。

      事件多播示例  

                EventDemo demo = new EventDemo();
                //注册事件
                demo.SomeEvent += Handler;
                //事件多播,
                demo.SomeEvent += MoreMethod.MoreMethodForEvent;
    
                //事件发生
                demo.OnSomeEvent();
                Console.ReadKey();
    View Code

      运行结果:

      

      

      事件存取器

      事件存取器类似属性存取器操作,通过存取器对事件控制更加灵活。

      事件可以使用匿名函数、和Lambda表达式,由于事件基本委托,所以事件的匿名函数、Lambda表达式同委托一样。

      

      .NET事件的指导原则

       为了使编写的组件与window兼容,开发人员需要遵循Microsoft建立的指导原则。事件处理程序必须有两个参数,

       第一个参数是产生事件的对象的引用,第二个参数为EventArgs类型。

       为了使事件遵循指导原则,再声明委托时使用delegate void MyEvent(object sender,EventArgs e),当然如果

        委托这么声明,那么委托调用的方法也要这样定义。

  • 相关阅读:
    列表的排序和统计。
    pyoo6 列表 004
    py005 列表 03
    py004列表02
    py 003 列表01
    py。002 字符串(str)
    py_001 运算符
    【python--字典】 字典的嵌套
    【python--字典】 字典的增删改查
    【python--字典】 字典的有效性
  • 原文地址:https://www.cnblogs.com/bro-ma/p/6696984.html
Copyright © 2020-2023  润新知