C#中事件只能在内部调用的原因分析

作者:cavalier23 时间:2023-08-09 05:07:00 

在学习C#中委托和事件时,产生一个疑问,类中定义的事件在类内部可以直接调用,而在类外部,事件却只能添加或移除委托方法

比如下面这段代码,类Customer中定义了一个委托 Order ,Customer内部可以直接调用 Order.Invoke()


public class Customer
   {
    // 定义事件
       public event  OrderEventHandler Order;
       public string? name;
       public float? price;
       protected void onOrder(OrderEventArgs orderEventArgs)
       {
           if(Order != null)
           {
               Order.Invoke(this, orderEventArgs);
           }
       }
    ......

而在类的外部,只能添加或移除委托方法,不能调用Order.Invoke(),下面代码中customer.Order.Invoke()会报错。


public class Program{
       public static void Main(string[] args)
       {
           var customer = new Customer();
           customer.name = "1";
           Waiter waiter = new Waiter();
           customer.Order += waiter.Serve;
          //  customer.Order.Invoke() 这样写无法编译
           customer.Think();
           customer.Pay();
       }
   }

细看刘铁猛老师的《C#入门详解》后,才明白原来这是C#语法糖让我产生的误解,在定义事件时,

下面这行代码是常见的定义方式,这是一种简明的定义方法


// 事件的简明定义方式
public event  OrderEventHandler Order;
而C#中事件完整的定义方式是这样:
       private OrderEventHandler orderEventHandler;//委托,使用private 修饰
       public event  OrderEventHandler Order // 事件,对委托方法进行增减
       {
           add
           {
               this.orderEventHandler += value;
           }
           remove
           {
               this.orderEventHandler -= value;
           }
       }

使用完整写法定义事件后,在内部调用也不能用事件Order去调用了,要用委托去调用


    protected void onOrder(OrderEventArgs orderEventArgs)
       {
           if(this.orderEventHandler != null)
           {
               // 调用委托
               this.orderEventHandler.Invoke(this, orderEventArgs);
           }
       }

可以看到,我们真正调用的委托使用private修饰,是私有的,所以只能在内部调用,而事件(event)则是对私有的委托进行了包装,实现对委托方法的增加或移除。

刚学C#,不知道说清楚没。。。

来源:https://www.cnblogs.com/cavaliers20160620/archive/2021/11/26/15605758.html

标签:C#,事件,内部调用
0
投稿

猜你喜欢

  • Java日常练习题,每天进步一点点(53)

    2023-08-12 00:55:00
  • Java解析XML的四种方法详解

    2022-07-02 23:39:33
  • C# 多网卡 Server Listen

    2022-05-30 16:09:18
  • 不使用他人jar包情况下优雅的进行dubbo调用详解

    2022-04-20 11:43:46
  • C#客户端程序Visual Studio远程调试的方法详解

    2022-10-20 19:13:54
  • Spring boot2X负载均衡和反向代理实现过程解析

    2023-02-06 04:18:53
  • c#创建windows服务入门教程实例

    2023-02-24 11:31:31
  • springboot表单提交之validator校验

    2023-05-16 23:19:17
  • 浅谈C#中堆和栈的区别(附上图解)

    2022-02-15 14:05:09
  • Kotlin 匿名类实现接口和抽象类的区别详解

    2021-09-04 07:14:58
  • Android应用自动更新功能实现的方法

    2022-12-02 07:01:53
  • Android 使用viewpager实现无限循环(定时+手动)

    2023-12-09 07:43:56
  • C#实现记事本查找与替换功能

    2022-03-24 00:20:58
  • 在idea中显示springboot面板的方法

    2022-01-02 22:00:57
  • Android蓝牙库FastBle的基础入门使用

    2021-09-21 07:34:21
  • Spring Cloud项目前后端分离跨域的操作

    2022-05-20 08:11:16
  • 基于AForge实现C#摄像头视频录制功能

    2023-08-25 02:21:26
  • Java如何获取对象属性及对应值

    2022-03-30 07:03:05
  • .net与javascript脚本的交互方法总结

    2021-09-11 09:21:32
  • 一篇文章轻松搞懂Java中的自旋锁

    2023-06-29 00:00:36
  • asp之家 软件编程 m.aspxhome.com