委托和事件

事件是保护的委托。其实就是限制了某些操作的委托。

这里的操作是赋值操作。

比如下面的例子:

    public delegate void DoSomeThing();
    public class Alarm
    {
        public DoSomeThing Do; //这里是一个委托

        public event TimeOutHandler OnTimeOut;

        private int _count = 10;
        private Timer _timer;

        public Alarm(int count)
        {
            _count = count;
            _timer = new Timer();
            _timer.Elapsed += _timer_Elapsed;
        }

        void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _count--;
            Console.WriteLine("time: " + _count);
            if (_count == 0)
            {
                Console.WriteLine("time out");
                if (Do != null)
                {
                    Do();
                }

                _timer.Stop();
            }
        }

        public void Start()
        {
            _timer.Start();
        }
    }

使用:

        static void Main(string[] args)
        {
            var alarm = new Alarm(5);
            alarm.Do += Eat;
            alarm.Do += Run;
            alarm.Do += Sleep;
  
            alarm.Start();

            Console.Read();
        }

结果:

一切看起来很好,但是如果我们修改一下调用:

        static void Main(string[] args)
        {
            var alarm = new Alarm(5);
            alarm.Do += Eat;
            alarm.Do += Run;
            alarm.Do = Sleep; //注意这里。

            alarm.Start();

            Console.Read();
        }

看下运行结果:

OMG , alarm.Do = Sleep; 这句代码将上面注册的事件都吃掉了。。。这是很不安全的。
所以event出来的了。
下面使用事件重写上面的例子:


    public class Alarm
    {
        public event DoSomeThing Do; //这里是一个事件   

        private int _count = 10;
        private Timer _timer;

        public Alarm(int count)
        {
            _count = count;
            _timer = new Timer();
            _timer.Elapsed += _timer_Elapsed;
        }

        void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _count--;
            Console.WriteLine("time: " + _count);
            if (_count == 0)
            {
                Console.WriteLine("time out");
                if (Do != null)
                {
                    Do();
                }

                _timer.Stop();
            }
        }

        public void Start()
        {
            _timer.Start();
        }
    }

再按照那种不安全的方法调用:

        static void Main(string[] args)
        {
            var alarm = new Alarm(5);
            
            alarm.Do += Eat;
            alarm.Do += Run;
            alarm.Do = Sleep; //这里会编译报错

            alarm.Start();

            Console.Read();
        }

编译不过去。。。
只能像下面的调用方法:

        static void Main(string[] args)
        {
            var alarm = new Alarm(5);
            
            alarm.Do += Eat;
            alarm.Do += Run;
            alarm.Do += Sleep;

            alarm.Start();

            Console.Read();
        }
posted @ 2015-11-30 09:31  le0zh  阅读(144)  评论(0编辑  收藏  举报