为什么不能在子类或外部发布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 ...
随机推荐
- Socket 学习(三).1 tcp 通讯
实现了,局域网客户端 对客户端 的通讯. 实际上这是 一个 客户端 兼 服务端 . 2个阿里云服务器测试 效果图: 本地效果图: using System; using System.Collecti ...
- 使用.NET REACTOR制作软件许可证
原文:使用.NET REACTOR制作软件许可证 软件下载地址:http://www.eziriz.com/downloads.htm 做一个简单的许可证系统,下面是具体步骤: 1, OPEN AS ...
- MySQL 一般查询日志(General Query Log)
与大多数关系型数据库,日志文件是MySQL数据库的一个重要组成部分.MySQL有几种不同的日志文件,通常包括错误日志文件,二进制日志,通用日志.慢查询日志,等等. 这些日志能够帮助我们定位mysqld ...
- Installshield停止操作系统进程的代码--IS5版本适用
原文:Installshield停止操作系统进程的代码--IS5版本适用 出处:http://www.installsite.org/pages/en/isp_ext.htm这个地址上有不少好东西,有 ...
- Spring源深和六系列 CreateBean过程
blog宗旨:用图说话. 这一章的图讲述了createBean的过程.到这里spring容器就能够完毕IOC的整个过程,拿到我们须要的对象. 下一章我们接着来看一看AOP完毕的过程. 附:文件夹 Sp ...
- NHibernate中使用memcache二级缓存
在NHibernate中使用memcache二级缓存 一.Windows下安装Memcache 1. 下载 http://jehiah.cz/projects/memcached-win32/ ...
- xfire集成spring构建webservice
前言:xfire.spring都是比较流行的技术,这里就不再赘述他们各自的优点:本文着重介绍xfire和spring的整合,不会做太深入的探究. 服务端 1. web.xml配置 spring配置部分 ...
- ubuntu新内核不能用启动回滚到旧内核的方法
先看一看自己电脑上有哪些内核文件 merlin@tfAnalysis:~$ dpkg --get-selections|grep linux libselinux1:i386 install linu ...
- 添加MySql Metat Database 信息
有时候我们想看看 一个数据库上面 某种元素(比如表名)的所有信息,在Mysql上 我们可以通过引入information_schema 的方式,就可以非常方便的查看到. 添加步骤 Edit->P ...
- 【MS SQL】数据库维护计划之数据库备份(一)
原文:[MS SQL]数据库维护计划之数据库备份(一) 在做数据库备份之前,一定会听到:完整备份.差异备份.增量备份.事务日志备份...等词:下面配图进行说明. 完整备份:完整数据库备份包含数据库中的 ...