为什么不能在子类或外部发布C#事件
为什么不能在子类或外部发布C#事件
背景
一个朋友问了一个问题:“为什么不能在子类或外部发布C#事件?”,我说我不知道,要看看生产的IL代码,下面我们看看。
测试
代码

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace EventStudy
8 {
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 }
14 }
15
16 class Base
17 {
18 private Action _testEventB;
19
20 public event Action TestEventA;
21
22 public event Action TestEventB
23 {
24 add
25 {
26 _testEventB += value;
27 }
28 remove
29 {
30 _testEventB -= value;
31 }
32 }
33
34 protected void OnTestEventA()
35 {
36 var testEventA = this.TestEventA;
37
38 testEventA();
39 }
40
41 protected void OnTestEventB()
42 {
43 var testEventB = _testEventB;
44
45 testEventB();
46 }
47 }
48
49 class Child : Base
50 {
51 public void Do()
52 {
53 //this.TestEventA();不能这样访问
54 }
55 }
56 }

IL

分析
1、TestEventA和TestEventB最终生成的代码结构基本一样,可以知道C#编译器帮我们做了一些工作。
2、其实C#编译器应该可以做到允许我们直接调用的,比如:生成的字段为protected类型,考虑到封装性,编译器没这么做,我觉得是合理的。
一则笑话
一位老先生问我如何拷贝文件,我说Control+C,然后Control+V,第二天他告诉我不行,后来发现他是在公司Control+C,回到家里Control+V的。
今天发生了真人版的这个事情,一位非常有前途的兄弟,在一个基类里定义了一个Event,有两个子类,分别为A和B,在A的实例里发布Event,在B的实例里监听这个Event。
一个问题
为什么一定要这么发布事件(引入一个局部变量):

1 protected void OnTestEventA()
2 {
3 var testEventA = this.TestEventA;
4
5 testEventA();
6 }

背景
找个机会得看看一些C#本质之类的书了,很多概念我也不是很清楚!
为什么不能在子类或外部发布C#事件的更多相关文章
- .NET:为什么不能在子类或外部发布C#事件
背景 一个朋友问了一个问题:“为什么不能在子类或外部发布C#事件?”,我说我不知道,要看看生产的IL代码,下面我们看看. 测试 代码 using System; using System.Collec ...
- Android 使用RxJava实现一个发布/订阅事件总线
1.简单介绍 1.1.发布/订阅事件主要用于网络请求的回调. 事件总线可以使Android各组件之间的通信变得简单,而且可以解耦. 其实RxJava实现事件总线和EventBus比较类似,他们都依据与 ...
- GL.IssuePluginEvent 发布插件事件
Description 描述 Send a user-defined event to a native code plugin. 发送一个用户定义的事件到一个本地代码插件. Rendering in ...
- Spring Boot 外部化配置(一)- Environment、ConfigFileApplicationListener
目录 前言 1.起源 2.外部化配置的资源类型 3.外部化配置的核心 3.1 Environment 3.1.1.ConfigFileApplicationListener 3.1.2.关联 Spri ...
- dubbo-源码阅读之服务发布
原理 dubbo根据spring 2.0的schma实现 解析xml并初始化相关bean 初始化dubbo:service为ServiceBean实例 通过spring的生命周期相应回调实现服务发布 ...
- 关于js调用外部部署的web api
没想到多年之后我还得继续写这些东西.... 瀑布汗~ 最近不得不开始研究用web api MVC的项目中,在js文件里,实现点击一个按钮调用外部发布好的api,再从api把值回传给js页面,跳转. 经 ...
- 软件发布版本区别介绍-Alpha,Beta,RC,Release
Alpha: Alpha是内部测试版,一般不向外部发布,会有很多Bug.除非你也是测试人员,否则不建议使用. 是希腊字母的第一位,表示最初级的版本 alpha就是α,beta就是β alpha版就是比 ...
- Delphi事件列表赏析(38个事件,必须要对这些事件非常熟悉,才能如臂使指,才能正确发布到新控件!)
我把Delphi常用的几个类的事件都收集齐了,并一一加以注释.原因是在自定义的过程中,看到那堆长长的事件列表感到头晕,但是如果不发布这些事件的话,更是暴殄天物.所以关键还是要对这些事件非常熟悉,才能不 ...
- java_软件发布版本_Asynch HttpClien 对比发行版本说明_Alpha、Beta、RC、GA版本的区别
今天看了一天的apache 的httpasyncclient ,为了和默认的httpclient做个对比,httpcore是核心轻量级的提供传统阻塞IO 和 java NIO两种方式,httpclie ...
随机推荐
- Web API 2 对 CORS 的支持
Web API 2 对 CORS 的支持 CORS概念 跨域资源共享 (CORS) 是一种万维网联合会 (W3C) 规范(通常被认为是 HTML5 的一部分),它可让 JavaScript 克服由浏览 ...
- Swift语言指南(九)--基本运算符
原文:Swift语言指南(九)--基本运算符 运算符(operator)是用来检查,改变或合并值的一种特殊符号或短语.例如,加号运算符让两个数字相加(如:let i = 1 + 2),还有些更复杂的运 ...
- github basic usage in windows
1. create a new accout, create orginazation, create repo 2. install git in your local pc Note: you c ...
- BZOJ 3282 Tree Link-Cut-Tree(LCT)
题目大意: 给定N个点以及每一个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y ...
- Python学习笔记:概要
1.print不同的互动解释语句输出和输出 在以下示例,我们分配字符串值到可变myString.先用print 要显示一个变量的内容, 其次是变量名,以显示. >>> myStrin ...
- 一道关于CSS选择器优先级的题
<span style="font-size:14px;"><html> <head> <style type="text/cs ...
- CORS跨域资源共享
CORS(跨域资源共享)跨域问题及解决 当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Co ...
- leetcode第36题--Sudoku Solver
题目: Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated b ...
- Ajax实现在textbox中输入内容,动态从数据库中模糊查询显示到下拉框中
功能:在textbox中输入内容,动态从数据库模糊查询显示到下拉框中,以供选择 1.建立一aspx页面,html代码 <HTML> <HEAD> <title>We ...
- TRIGGER的使用(修改SP自动触发)
CREATE TRIGGER [trg_save_change_SP] ON DATABASE FOR CREATE_PROCEDURE, ALTER_PROCEDURE,DROP_PROCEDURE ...