C# 事件

最近又重新看了看事件,这篇文章不错。测试了里面的代码。

说事件前,得先提提委托。

using UnityEngine;
using System.Collections;

namespace TZ_delegate_event
{
    public delegate void GreetingDelegate(string name);

    ///使用委托5
    public class GreetingManager
    {
        //声明委托
        public GreetingDelegate delegate1;

        public void GreetPeople(string name)
        {
            if (delegate1 != null)
            {
                delegate1(name);
            }
        }
    }

    ///使用事件
    //在类的内部,不管你声明它是public还是protected,它总是private 的。在类的外部,注册“+=”和注销“-=”的访问限定符与你在声明事件时使用的访问符相同
    public class GreetingPeople2
    {
        //声明事件 事件相对委托多了一个event关键字
        public event GreetingDelegate MakeGreet; //就算事件前有public修饰,但其调用也只能在当前类中

        public void GreetPeople(string name)
        {
            MakeGreet(name);
        }
    }

    public class Event_Test : MonoBehaviour
    {
        #region
        ///使用普通函数
        //public void GreetPeople(string name)
        //{
        //    EnglishGreeting(name);
        //}

        public enum Language
        {
            English,
            Chinese
        }

        public void GreetPeople(string name, Language lang)
        {
            switch (lang)
            {
                case Language.Chinese:
                    ChineseGreeting(name);
                    break;
                case Language.English:
                    EnglishGreeting(name);
                    break;
                default: break;
            }
        }

        public void EnglishGreeting(string name)
        {
            Debug.Log("Good Morning," + name);
        }

        public void ChineseGreeting(string name)
        {
            Debug.Log("早上好," + name);
        }

        ///使用委托1
        //public delegate void GreetingDelegate(string name);

        public void GreetingPeople(string name, GreetingDelegate MakeGreeting)
        {
            MakeGreeting(name);
        }
        #endregion
        // Use this for initialization
        void Start()
        {
            #region
            //普通函数
            Debug.Log("普通函数");
            GreetPeople(" Jim", Language.English);

            //使用委托1
            Debug.Log("使用委托1");
            GreetingPeople(" Jim", EnglishGreeting);

            //使用委托2
            Debug.Log("使用委托2");
            GreetingDelegate delegate1, delegate2;
            delegate1 = EnglishGreeting;
            delegate2 = ChineseGreeting;
            GreetingPeople(" Jim", delegate1);
            GreetingPeople(" Jim", delegate2);

            //使用委托3
            Debug.Log("使用委托3");
            GreetingDelegate delegate3;
            delegate3 = EnglishGreeting;
            delegate3 += ChineseGreeting;
            GreetingPeople(" Jim", delegate3);

            //使用委托4
            Debug.Log("使用委托4");
            GreetingDelegate delegate4;
            delegate4 = EnglishGreeting;
            delegate4 += ChineseGreeting;
            delegate4(" Jim");

            //使用委托5
            Debug.Log("使用委托5");
            GreetingManager gm = new GreetingManager();
            gm.delegate1 = EnglishGreeting;
            gm.delegate1 += ChineseGreeting;
            gm.GreetPeople(" Jim");
            #endregion

            //使用事件
            Debug.Log("使用事件");
            GreetingPeople2 g = new GreetingPeople2();
            //编译错误
            //g.MakeGreet = EnglishGreeting; //事件右侧只能是+=或-=
            g.MakeGreet += EnglishGreeting;
            g.MakeGreet += ChineseGreeting;
            g.GreetPeople(" Jim");
        }

        // Update is called once per frame
        void Update()
        {

        }
    }
}

事件应该由事件发布者触发,而不应该由事件的客户端(客户程序)来触发

using UnityEngine;
using System.Collections;

namespace TZ_delegate_event1
{
    //事件应该由事件发布者触发,而不应该由事件的客户端(客户程序)来触发

    /// 
    /// 定义委托
    /// 
    /// 
    public delegate void NumberChangeEventHandle(int count);

    /// 
    /// 定义事件发布者
    /// 
    public class Publishser
    {
        private int count;
       // public NumberChangeEventHandle NumberChanged; //声明委托变量
        public event NumberChangeEventHandle NumberChanged; //声明委托变量

        public void DoSomething()
        {
            //在这里完成工作

            if (NumberChanged != null)
            {
                count++;
                NumberChanged(count);
            }
        }
    }

    /// 
    /// 定义事件订阅者
    /// 
    public class Subscriber
    {
        public void OnNumberChanged(int count)
        {
            Debug.Log("Subscriber notified : count = " + count);
        }
    }

    public class Event_Test1 : MonoBehaviour
    {
        // Use this for initialization
        void Start()
        {
            Publishser pub = new Publishser();
            Subscriber sub = new Subscriber();
            pub.NumberChanged += new NumberChangeEventHandle(sub.OnNumberChanged);
            pub.DoSomething(); //应该通过DoSomething()来触发事件
            //pub.NumberChanged(100); //如果是委托,可以被这样调用,这是对委托变量的不恰当使用;如果是事件,这直接编译报错。
        }

        // Update is called once per frame
        void Update()
        {

        }
    }
}

事件的一个例子

using UnityEngine;
using System.Collections;

namespace TZ_delegate_event2
{
    /*
    //热水器
    public class Heater
    {
        //水温
        private int temperature;

        /// 
        /// 烧水
        /// 
        public void BoilWater()
        {
            for (int i = 0; i <= 100; ++i)
            {
                temperature = i;
                if (temperature > 95)
                {
                    MakeAlert(temperature);
                    ShowMsg(temperature);
                }
            }
        }

        /// 
        /// 发出语音警报
        /// 
        /// 
        private void MakeAlert(int param)
        {
            Debug.Log("水已经" + param + "度了");
        }

        /// 
        /// 显示水温
        /// 
        /// 
        private void ShowMsg(int param)
        {
            Debug.Log("水快开了,当前温度:" + param);
        }
    }
       */

    //热水器
    public class Heater
    {
        private int temperature;

        public delegate void BoilHandle(int param);

        public event BoilHandle BoilEvent;

        public void BoilWater()
        {
            for (int i = 0; i <= 100; ++i)
            {
                temperature = i;
                if (temperature > 95)
                {
                    if (BoilEvent != null)
                    {
                        BoilEvent(temperature); //调用所有注册对象的方法
                    }
                }
            }
        }
    }

    //报警器
    public class Alarm
    {
        public void MakeAlert(int param)
        {
            Debug.Log("水已经" + param + "度了");
        }
    }

    //显示
    public class Display
    {
        public static void ShowMsg(int param) //静态方法
        {
            Debug.Log("水快开了,当前温度:" + param);
        }
    }

    public class Event_Test2 : MonoBehaviour
    {
        // Use this for initialization
        void Start()
        {
            /*
            Heater h = new Heater();
            h.BoilWater();
            */

            Heater h = new Heater();
            Alarm al = new Alarm();
            h.BoilEvent += al.MakeAlert; //注册方法
            h.BoilEvent += (new Alarm()).MakeAlert; //给匿名对象注册方法
            h.BoilEvent += Display.ShowMsg; //注册静态方法
            h.BoilWater(); //烧水,会自动调用注册过的对象方法
        }

        // Update is called once per frame
        void Update()
        {

        }
    }
}


上面例子的延伸

using UnityEngine;
using System.Collections;
using System;

namespace TZ_delegate_event3
{
    //不光想获得热水器的温度,还想在Observer 端(警报器或者显示器)方法中获得它的生产日期、型号、价格
    //热水器
    public class Heater
    {
        private int temperature;
        public string type = "xxx 001"; //型号
        public string area = "China"; //产地

        public delegate void BoilEventHandle(System.Object sender, BoiledEventArgs e);

        public event BoilEventHandle BoilEvent; //声明事件

        //定义BoiledEventArgs类,传递给Observer所感兴趣的信息
        public class BoiledEventArgs : EventArgs
        {
            public readonly int temperature;
            public BoiledEventArgs(int temperature)
            {
                this.temperature = temperature;
            }
        }

        //可以供继承自Heater的类重写,以便继承类拒绝其他对象对它的监视
        protected virtual void OnBoiled(BoiledEventArgs e)
        {
            if (BoilEvent != null)
            {
                BoilEvent(this, e); //调用所有注册对象的方法
            }
        }

        public void BoilWater()
        {
            for (int i = 0; i <= 100; ++i)
            {
                temperature = i;
                if (temperature > 95)
                {
                    //建立BoiledEventArgs对象
                    BoiledEventArgs e = new BoiledEventArgs(temperature);
                    OnBoiled(e); //调用OnBoiled方法
                }
            }
        }
    }

    //报警器
    public class Alarm
    {
        public void MakeAlert(System.Object sender, Heater.BoiledEventArgs e)
        {
            Heater h = (Heater)sender;

            //访问sender中的公共字段
            Debug.Log("Alarm 产地:" + h.area + " 型号:" + h.type);
            Debug.Log("水已经" + e.temperature + "度了");
        }
    }

    //显示
    public class Display
    {
        public static void ShowMsg(System.Object sender, Heater.BoiledEventArgs e) //静态方法
        {
            Heater h = (Heater)sender;
            Debug.Log("Display 产地:" + h.area + " 型号:" + h.type);
            Debug.Log("水快开了,当前温度:" + e.temperature);
        }
    }

    public class Event_Test3 : MonoBehaviour
    {
        // Use this for initialization
        void Start()
        {
            Heater h = new Heater();
            Alarm a = new Alarm();
            h.BoilEvent += a.MakeAlert; //注册方法
            h.BoilEvent += (new Alarm()).MakeAlert; //给匿名对象注册方法
            h.BoilEvent += new Heater.BoilEventHandle(a.MakeAlert); //也可以这么注册
            h.BoilEvent += Display.ShowMsg; //注册静态方法
            h.BoilWater(); //烧水,会自动调用注册过的对象方法
        }

        // Update is called once per frame
        void Update()
        {

        }
    }
}

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值