• 既然有了委托为什么还要有事件?


    语法和定义方面,基本上都是知道的,但很多人肯定也会迷惑,什么时候该用事件,什么时候该用委托

    或者说,既然有了委托为什么还要有事件?,

    委托相对事件来说,安全性和封装性没有事件高

    其实对于这些定义我也讲不太清楚,无非就是把一大段一大段的定义给摘抄过来罢了

    所以不讲那些,直接看例子好了

    ===========================================================================

    我们来假设一个不是特别恰当的例子

    有一个动物园,它的开园时间是09:00-18:00,在开园内可以允许游客游玩,至于游客玩什么,不在意

    先看代码例子

    class Program
        {
            static void Main (string[] args)
            {
                Zoo z = new Zoo ();
                //设置入园时间
                z.Time = 11;
                //给委托赋值
                z.play += () => { Console.WriteLine ("看狮子去!"); };
                //开始游玩
                z.Open ();
                Console.ReadKey ();
            }
        }
    
        /// <summary>
        /// 动物园类
        /// </summary>
        public class Zoo
        {
            /// <summary>
            /// 入园时间
            /// </summary>
            public int Time { get; set; }
    
            /// <summary>
            /// 无参的委托
            /// </summary>
            public delegate void Play ();
    
            /// <summary>
            /// 创建委托对象
            /// </summary>
            public Play play;
    
            /// <summary>
            /// 开园了
            /// </summary>
            public void Open ()
            {
                //如果当前时间在9:00-18:00之间
                if ( Time > 9 && Time < 18 )
                {
                    //游客可以选择游玩方式
                    play?.Invoke ();
                }
                else
                {
                    Console.WriteLine ("还未到开园时间,敬请等待");
                }
            }
        }
    

      

    可以看到,委托成功被调用了

    但是,如果我们在Main方法中更改两个地方

     static void Main (string[] args)
            {
                Zoo z = new Zoo ();
                //设置入园时间
                z.Time = 19;
                //给委托赋值
                z.play += () => { Console.WriteLine ("看狮子去!"); };
                //开始游玩
                z.Open ();
                //我直接调用委托
                z.play ();
                Console.ReadKey ();
            }
    

      将入园时间改成19点,然后直接调用z.play(),看看会发生什么

    你会发现,没到开园时间,但游客仍然能去看狮子

    这就明显不合道理了,我动物园都没开门,你丫直接翻墙进去了???

    所以对于这种情况,就不适合用委托了,这时候,事件就该登场了

    把代码改一改

     class Program
        {
            static void Main (string[] args)
            {
                Zoo z = new Zoo ();
                //设置入园时间
                z.Time = 19;
                //给委托赋值
                z.play += () => { Console.WriteLine ("看狮子去!"); };
                //开始游玩
                z.Open ();
                //我直接调用委托
               // z.play (); //改为事件后,这里将不能直接调用,会报错
                
                Console.ReadKey ();
            }
        }
       
        /// <summary>
        /// 动物园类
        /// </summary>
        public class Zoo
        {
            /// <summary>
            /// 入园时间
            /// </summary>
            public int Time { get; set; }
    
            /// <summary>
            /// 无参的委托
            /// </summary>
            public delegate void Play ();
    
            /// <summary>
            /// 创建事件委托对象
            /// </summary>
            public event Play play;
    
            /// <summary>
            /// 开园了
            /// </summary>
            public void Open ()
            {
                //如果当前时间在9:00-18:00之间
                if ( Time > 9 && Time < 18 )
                {
                    //游客可以选择游玩方式
                    play?.Invoke ();
                }
                else
                {
                    Console.WriteLine ("还未到开园时间,敬请等待");
                }
            }
        }
    

      我只更改了两个地方,将

    public Play play;

    改为了
    public event Play play;

    只多加了个event关键字
    然后在Main函数中的z.play ();就不能够调用了
    这样也就不用担心游客翻墙了,运行一下


    ===============================================================================================
    一点浅见,仅供笑言
  • 相关阅读:
    正则表达式系统教程 [转,主要是自己备忘] 碧血黄沙
    vim打开txt文件看到^@字符
    使用PuTTY软件远程登录root被拒:access denied
    Using CustomProperties of CodeSmith
    ASP:Literal控件用法
    ASP.NET2.0中配置文件的加密与解密
    Enterprise Library 2.0 Data Access Application Block (补充)
    Infragistics中WebGrid的MultiColumn Headers设计
    世界杯揭幕战比分预测
    Enterprise Library1.0 DataAccess Application Block
  • 原文地址:https://www.cnblogs.com/rbzz/p/9908007.html
Copyright © 2020-2023  润新知