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

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

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

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

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

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

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

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

有一个动物园,它的开园时间是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 ();就不能够调用了
这样也就不用担心游客翻墙了,运行一下


===============================================================================================
一点浅见,仅供笑言
原文地址:https://www.cnblogs.com/rbzz/p/9908007.html