c# 委托与事件

事件

事件(event)基于委托,为委托提供一个发布/订阅机制,我们可以说事件是一种具有特殊签名的委托。
什么是事件?
  事件(event)是类或对象向其他类或对象通知发生的事情的一种特殊签名的委托。
事件的声明
  首先必须声明该事件的委托类型。例如
    public delegate void BoilerLogHandler(string status);
  然后,声明事件本身,使用 event 关键字:
    public event BoilerLogHandler BoilerEventLog;
  事件使用event关键字来声明,他的返回值是一个委托类型。
  通常事件的命名,以名字+Event作为他的名字。

事件与委托的联系与区别
  事件是一种特殊的委托,或者说是受限制的委托,在定义事件类的外部,只能施加+=、-=操作符。二者本质上是一个东西。
  委托可以在外部被直接调用,但事件不可以在定义类的外部被触发。

    class Program
    {
        static void Main(string[] args)
        {
            ToolMan toolMan = new ToolMan("小明");

            LazyMan lazyMan1 = new LazyMan("张三");
            LazyMan lazyMan2 = new LazyMan("李四");
            LazyMan lazyMan3 = new LazyMan("王五");

            toolMan.DownStairdelegate += lazyMan1.TakeFood;
            toolMan.DownStairdelegate += lazyMan2.TakePackage;
            toolMan.DownStairdelegate += lazyMan3.TakeFood;
            toolMan.DownStair();

            Console.WriteLine("。。。。。。。。。。。。。。。。。。。。");

            toolMan.DownStairdelegate -= lazyMan3.TakeFood;
            toolMan.DownStair();
            Console.Read();
        }
    }

    delegate void DownStairdelegate();
    internal class ToolMan
    {
        public string Name { get; private set; }
        public DownStairdelegate DownStairdelegate = null;
        public ToolMan(string name)
        {
            this.Name = name;
        }

        public void DownStair()
        {
            Console.WriteLine("工具人"+Name + "下楼了");
            if(DownStairdelegate != null)
            {
                DownStairdelegate();
            }
        }
    }

    internal class LazyMan
    {
        public string Name { get; private set; }

        public LazyMan(string name)
        {
            this.Name = name;
        }
        public void TakeFood()
        {
            Console.WriteLine("给" + Name + "拿外卖");
        }

        public void TakePackage()
        {
            Console.WriteLine("给" + Name + "拿快递");
        }
    }

运行结果:

工具人小明下楼了
给张三拿外卖
给李四拿快递
给王五拿外卖
。。。。。。。。。。。。。。。。。。。。
工具人小明下楼了
给张三拿外卖
给李四拿快递

是用委托来进行函数绑定,这样执行貌似没什么问题,但是…

    class Program
    {
        static void Main(string[] args)
        {
            ToolMan toolMan = new ToolMan("小明");

            LazyMan lazyMan1 = new LazyMan("张三");
            LazyMan lazyMan2 = new LazyMan("李四");
            LazyMan lazyMan3 = new LazyMan("王五");
            
            toolMan.DownStairdelegate += lazyMan1.TakeFood;
            toolMan.DownStairdelegate += lazyMan2.TakePackage;
            toolMan.DownStairdelegate = lazyMan3.TakeFood;//有可能一不小心覆盖掉了
            toolMan.DownStair();
            Console.Read();
        }
    }

运行结果:

工具人小明下楼了
给王五拿外卖

有可能会被一不小心覆盖掉原有的需执行内容

        static void Main(string[] args)
        {
            ToolMan toolMan = new ToolMan("小明");

            LazyMan lazyMan1 = new LazyMan("张三");
            LazyMan lazyMan2 = new LazyMan("李四");
            LazyMan lazyMan3 = new LazyMan("王五");
            
            toolMan.DownStairdelegate += lazyMan1.TakeFood;
            toolMan.DownStairdelegate += lazyMan2.TakePackage;
            toolMan.DownStairdelegate += lazyMan3.TakeFood;
            toolMan.DownStairdelegate();//外部进行了触发
            Console.Read();
        }
    }

运行结果:

给张三拿外卖
给李四拿快递
给王五拿外卖

有可能未达到函数运行条件,直接调用委托而执行了函数。

所以引入事件来规避一些异常情况,代码修改方法如下:
//将ToolMan类中的
public DownStairdelegate DownStairdelegate = null;
//改为
public event DownStairdelegate DownStairdelegate = null;

在这里插入图片描述
将委托改为事件之后,直接赋值与直接调用都将不被允许,这样的话就规避掉了委托在此应用下的弊端。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值