模拟C#的事件添加和删除
从《C# Via CLR》中的演化的一个小demo,探索事件的添加和删除原理,简单明了:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace ExpForEvent001
{
public sealed class EventKey : Object { } public sealed class EventSet
{
private readonly Dictionary<EventKey, Delegate> m_events = new Dictionary<EventKey, Delegate>(); public void Add(EventKey eventKey, Delegate handler)
{
Monitor.Enter(m_events);
Delegate d;
m_events.TryGetValue(eventKey, out d);
m_events[eventKey] = Delegate.Combine(d, handler);//Here we used Combine
Monitor.Exit(m_events);
} public void Remove(EventKey eventKey, Delegate handler)
{
Monitor.Enter(m_events);
Delegate d;
if (m_events.TryGetValue(eventKey, out d))
{
d = Delegate.Remove(d, handler); if (d != null) m_events[eventKey] = d;
else m_events.Remove(eventKey);
}
Monitor.Exit(m_events);
} public void Raise(EventKey eventKey, Object sender, EventArgs e)
{
Delegate d;
Monitor.Enter(m_events);
m_events.TryGetValue(eventKey, out d);
Monitor.Exit(m_events); if (d != null)
{
d.DynamicInvoke(new Object[]{ sender, e });
}
}
} public class FooEventArgs : EventArgs { } public class TypeWithLotsOfEvents
{
public readonly EventSet m_eventSet = new EventSet(); protected EventSet EventSet { get { return m_eventSet; } } #region Support Foo Event protected static readonly EventKey s_fooEventKey = new EventKey(); public event EventHandler<FooEventArgs> Foo
{
add { m_eventSet.Add(s_fooEventKey, value); }
remove { m_eventSet.Remove(s_fooEventKey, value); }
} protected virtual void OnFoo(FooEventArgs e)
{
m_eventSet.Raise(s_fooEventKey, this, e);
} public void SimulateFoo() { OnFoo(new FooEventArgs()); } #endregion
} class Program
{
static void Main(string[] args)
{
TypeWithLotsOfEvents twle = new TypeWithLotsOfEvents(); twle.Foo += HandleFooEvent1;
twle.Foo += HandleFooEvent2; twle.SimulateFoo();
} private static void HandleFooEvent1(object sender, FooEventArgs e)
{
Console.WriteLine("Handling Foo Event here...");
} private static void HandleFooEvent2(object sender, FooEventArgs e)
{
Console.WriteLine("Handling Foo Event here2...");
}
}
}
运行结果:

附带Richter大神的一段话:
“JIT编译器能判断代码是否运行在一个Intel Pentium 4 CPU上,并生成相应的本地代码来利用Pentium 4支持的任何【特殊】指令,相反,非托管代码通常是针对通用的、具有最小功能集合的CPU编译的,不会使用提升应用程序性能的特殊指令。”
My words:
不同的体系结构的计算机其指令集是有差别的。软件越抽象则离硬件越远,从而阻挡了我们看到问题实质的视野。
模拟C#的事件添加和删除的更多相关文章
- 【八】jqeury之click事件[添加及删除数据]
要求:1.添加数据显示在下方列表.2.添加的数据可动态删除. 界面显示: 代码: <!DOCTYPE html> <html> <head> <script ...
- jQuery focus、blur事件 添加、删除类名
jQuery.focusblur = function(ele,className){ var focusblurid = $(ele); focusblurid.focus(function(){ ...
- 原生js事件的添加和删除
在IE浏览器中添加或删除事件用attachEvent.detachEvent.在其他标准浏览器中则用addEventListener.removeEventListener.下面的对事件的添加和删除做 ...
- jquery 添加与删除的规律 当要添加时候要定位到自己的父元素 当要删除时候 通过事件函数传入的this找到自己的父元素进行删除
jquery 添加与删除的规律 当要添加时候要定位到自己的父元素 当要删除时候 通过事件函数传入的this找到自己的父元素进行删除
- 数组练习:各种数组方法的使用&&事件练习:封装兼容性添加、删除事件的函数&&星级评分系统
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- (三)根据向导创建MFC工程,事件的添加和删除
一,文档视图结构 文档:它是一个类,这个类专门用来存储数据 视图:它是一个类,这个类专门用来显示和修改数据 框架类:一个容器,这个容器装了视图 健完工程之后,类视图: 运行一下: 几个比较重要的函数 ...
- 第一百七十一节,jQuery,高级事件,模拟操作,命名空间,事件委托,on、off 和 one
jQuery,高级事件,模拟操作,命名空间,事件委托,on.off 和 one 学习要点: 1.模拟操作 2.命名空间 3.事件委托 4.on.off 和 one jQuery 不但封装了大量常用的事 ...
- JS数组方法汇总 array数组元素的添加和删除
js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^ var arr = new Array(); arr[0] = "aaa"; arr[ ...
- jQuery实现动态添加和删除一个div
本文主要给大家简单介绍一下如何动态的在一个元素添加和删除div,希望能够得到举一反三之效. 代码实例如下: <!DOCTYPE html> <html> <head> ...
随机推荐
- Python随机数生成方法
假设你对在Python生成随机数与random模块中最经常使用的几个函数的关系与不懂之处.以下的文章就是对Python生成随机数与random模块中最经常使用的几个函数的关系,希望你会有所收获,以下就 ...
- spring的统一异常处理
在控制器(controller)中添加统一异常处理的方法,在方法前面加@ExceptionHandler[(异常类.class)]注解
- python -- 解决If using all scalar values, you must pass an index问题
[问题描述] 在将dict转为DataFrame时会报错:If using all scalar values, you must pass an index 例如: summary = pd.Dat ...
- selenium webdriver处理HTML5 的视频播放
import org.openqa.selenium.By; import org.openqa.selenium.JavascriptExecutor; import org.openqa.sele ...
- iOS 网易彩票-5设置模块二
产品推荐 产品推荐使用的是UICollectionView控件,UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视 ...
- sql server删除重复数据,保留第一条
SELECT * FROM EnterpriseDataTools.Enterprise.CompanyMainwhere CompanyNo in (select CompanyNo from En ...
- Root :: AOAPC I: Beginning Algorithm Contests (Rujia Liu) Volume 7. Graph Algorithms and Implementation Techniques
uva 10803 计算从任何一个点到图中的另一个点经历的途中必须每隔10千米 都必须有一个点然后就这样 floy 及解决了 ************************************* ...
- Linux系统下C语言程序的构建过程
本文转载自:http://www.ruanyifeng.com/blog/2014/11/compiler.html 源码要运行,必须先转成二进制的机器码.这是编译器的任务. 比如,下面这段源码(假定 ...
- org.apache.catalina.core.StandardWrapperValve invoke的解决办法
org.apache.catalina.core.StandardWrapperValve invoke的解决办法 比较容易错的地方是页面带参数进行跳转,由于跳转之后的页面本身也要执行一部分sql语句 ...
- js将时间戳转化为日期格式
function getLocalTime(nS) { var date = new Date(nS); var Y = date.getFullYear() + '-'; ...