C#中事件只能在内部调用的原因分析
作者:cavalier23 发布时间:2023-08-09 05:07:00
标签:C#,事件,内部调用
在学习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


猜你喜欢
- 本文最终结果大概是这样的,使用java技术随机生成10个数,然后填充一个数组并在消息框中显示数组内容,接着对数组求和输出,将结果显示在消息框
- 一、堆的创建1、向下调整(以小堆为例) 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent
- 本文实例为大家分享了Java网络编程TCP实现文件上传的具体代码,供大家参考,具体内容如下上一篇博客,用网络编程TCP 实现聊天,这次实现文
- 生成前:public static void main(String[] args) { new HashMap<Stri
- java实现数字转大写的方法说明:将数字金额转大写,如下:public class Test { /** *
- 窗口是GUI编程的基础,小应用程序或图形界面的应用程序的可视组件都放在窗口中,在GUI中,窗口是用户屏幕的一部分,起着在屏幕中一个小屏幕的作
- 本文实例讲述了Java基于socket实现简易聊天室的方法。分享给大家供大家参考。具体实现方法如下:chatroomdemo.javapac
- 一般而言,Android 应用在请求数据时都是以 Get 或 Post 等方式向远程服务器发起请求,那你有没有想过其实我们也可以在 Andr
- 本文实例为大家分享了C语言实现三子棋小游戏的具体代码,供大家参考,具体内容如下设计思路三子棋的C语言设计的思路:1.设计一个界面:让玩家运行
- SQLite 介绍SQLite,是一款轻型的数据库,用于本地的数据储存。先说说优点,它占用资源非常的低,在嵌入式设备中需要几百K的内存就够了
- SpringBoot 工厂模式自动注入Map一、建立工厂类public interface AnimalFactory { S
- 主要代码:(有注释)package com.example.checkboxtest;import android.annotation.S
- 直译过来就是倒计数(CountDown)门闩(Latch)。倒计数不用说,门闩的意思顾名思义就是阻止前进。在这里就是指 CountDownL
- 修改加密和验证方法/** * 生成BCryptPasswordEncoder密码 *
- @TransactionalEventListener监听事务项目背景最近在项目遇到一个问题A方法体内有 INSERT、UPDATE或者DE
- 最近搞造价系统时遇到一些需要汇总的指标数据类似下面的结构指标A 1000指标B 500指标C 500指标A = B+C当我们需要对这些数值进
- 本文以实例形式分析了C#中Predicate<T>与Func<T, bool>泛型委托的用法,分享给大家供大家参考之
- 1.什么是WebSocketWebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信
- 配置文件中设置通常在公司级别的项目中,我们可能会写多个application- dev/prod.yml ,然后我们通常会在applicat
- 本文实例为大家分享了C语言实现餐饮管理系统的具体代码,供大家参考,具体内容如下#include <stdio.h>#includ