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