zoukankan      html  css  js  c++  java
  • 面向对象基础:委托事件

    当要把方法传送给其他方法时,需要使用委托

     委托和事件

    委托和事件这两个概念是完全配合的。委托仅仅是函数指针,那就是说,它能够引用函数,通过传递地址的机制完成。委托是一个类,当你对它实例化时,要提供一个引用函数,将其作为它构造函数的参数

    Event出场了,它封装了委托类型的变量,使得:在类的内部,不管你声明它是public还是protected,它总是private的。在类的外部,注册“+=”和注销“-=”的访问限定符与你在声明事件时使用的访问符相同

    事件其实没什么不好理解的,声明一个事件不过类似于声明一个进行了封装的委托类型的变量而已

    事件 :

    定义:是类在发生其关注的事情时用来提供通知的一种方式

    步骤:

    1. 基于委托定义事件(在当前类中/子窗体)

    2. 订阅事件(其他类/主窗体)

    3 触发事件(还是在当前类中/子窗体)

    事件的声明

    1.声明一个委托
    public delegate void EventHandler(object sender, System.EventArgs e);

    2.声明一个事件
    public event EventHandler Changed;

    3.引发一个事件
    public OnChanged(EnventArgs e)
    {
     if ( Changed != null)
     {
      Changed(this,e);
     }
    }

    4.定义事件处理程序
    public MyText_OnChanged(Object sender,EventArgs e)
    {
     ...
    }

    5.订阅事件(将事件处理程序添加到事件的调用列表中)

    myText.Changed += EventHandler(MyText_OnChanged);

    参考

    http://q.sohu.com/forum/5/topic/4212061

    1.0委托类型本质上就是一个类类型,委托类型可以定义委托对象(或委托变量),委托对象可以代表一个方法,委托对象所代表的方法是在创建委托对象时由委托的构造方法传入的,这个方法,可以是对象的实例方法也可以是类的静态方法.

    1.1委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数进行传递,当你对它实例化时,要提供一个引用函数,将其作为它构造函数的参数。

    2.委托的定义有个技巧,那就是你先定义要委托的方法,然后把这个方法的声明部分拷贝过来加一个delegate关键字就是要定义的委托.(因为委托在定义中,如果去掉delegate关键字剩下的也就是定义一个方法的语法)

    3.多播委托-引发连锁反应

    注:多播委托的委托方法最好是没有返回值的方法,也是就是void方法,如果委托了带有返回值的方法也无法获得级联的结果.(实例: DelegateEvent-DelegateOne)

    1. 事件机制运行原理

    事件发布者定义事件,并为事件订阅接收者,然后发布者发布事件,事件的接收者接收事件,并调用自己的方法处理事件,这就是事件机制运行原理

    注:1.事件的定义,需要一个委托类型,这个委托类型用来将来要处理事件的方法类型 2.接收事件,必须在事件的接收者类里提供和事件定义时,委托类型相同的方法 3.订阅接收者,事件的订阅通过”+=”操作符,事件的订阅和多播委托的操作一样,可以给事件添加一个或多个方法委托.

    实际上,程序中的事件处理只有三步,第一步是定义事件,第二步订阅事件,第三步就是激发事件

    public delegate void BusinessChangedDelgegate(RecordState businessRecordState);

    public event BusinessChangedDelgegate BusinessChange;

    mainBusinessForm.BusinessChange += new BusinessChangedDelgegate(mainBusinessForm_BusinessChange);

    C#事件与委托实例Demo源代码(实现:遥控器遥控电视)

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace DelegateEvent
    {
        /// <summary>
        /// 遥控器类
        /// </summary>
        class RemoteControl//事件引发者
        {
            public delegate void delegateOpenClose();//遥控器上的开关
            public delegate void delegateEnterNum(int n);
            public event delegateOpenClose delegateOpenEvent;//遥控器上的开键
            public event delegateOpenClose delegateCloseEvent;//遥控器上的关键
            public event delegateEnterNum delegateEnterNumEvent;//遥控器上的选台键
            public void Open()
            {
                if (delegateOpenEvent != null)
                    delegateOpenEvent();
                //如果事件有响应者,发送事件给响应者
            }
            public void Close()
            {
                if (delegateCloseEvent != null)
                    delegateCloseEvent();
            }
            public void SelectChannel(int n)
            {
                if (delegateEnterNumEvent != null)
                    delegateEnterNumEvent(n);
            }
        }
        /// <summary>
        /// 电视类
        /// </summary>
        public  class Television //事件响应者
        {
            /// <summary>
            /// 事件处理方法
            /// </summary>
            public void OpenTelv()
            {
                Console.WriteLine("屏幕亮了");
            }
            public void CloseTelv()
            {
                Console.WriteLine("屏幕黑了");
            }
            public void ChangeChannel(int n)
            {
                Console.WriteLine("频道{0}播放", n);
            }
        }
        class Program//用于触发事件
        {
            static void Main(string[] args)
            {
                RemoteControl remote = new RemoteControl();
                Television telv = new Television();
                //方法一
                remote.delegateCloseEvent += new RemoteControl.delegateOpenClose(telv.CloseTelv);
                remote.delegateOpenEvent += new RemoteControl.delegateOpenClose(telv.OpenTelv);
                remote.delegateEnterNumEvent += new RemoteControl.delegateEnterNum(telv.ChangeChannel);
                //方法二
                //remote.delegateCloseEvent += remote_delegateCloseEvent;
                //remote.delegateOpenEvent += remote_delegateOpenEvent;
                //remote.delegateEnterNumEvent += remote_delegateEnterNumEvent;
                //开始触发事件
                remote.Open();
                remote.SelectChannel(20);
                remote.SelectChannel(10);
                remote.Close();
                Console.ReadLine();
            }
    
            //static void remote_delegateEnterNumEvent(int n)
            //{
            //    Console.WriteLine("频道{0}播放", n);
            //}
            //static void remote_delegateOpenEvent()
            //{
            //    Console.WriteLine("屏幕亮了");
            //}
    
            //static void remote_delegateCloseEvent()
            //{
            //    Console.WriteLine("屏幕黑了");
            //}
        }
    }

    转摘 请备注出处

  • 相关阅读:
    C#刷遍Leetcode系列连载 索引
    C#刷遍Leetcode面试题系列连载(2): No.38
    C#刷遍Leetcode面试题系列连载(1)
    Windows新终端中玩转ASCII和Emoji游戏的正确姿势
    终于等到你!微软正式上线 Windows Terminal 预览版
    任意公众号的文中插入外链的方法找到了,亲测有效
    只需3步,即可将你的Chromium Edge 浏览器设置成中文
    重磅福利 | 知乎上赞同数最高的1000个回答2019最新版
    黑科技抢先尝(续)
    GitHub上最火爆!码代码不得不知的所有定律法则
  • 原文地址:https://www.cnblogs.com/lqsilly/p/2936249.html
Copyright © 2011-2022 走看看