从《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#的事件添加和删除的更多相关文章

  1. 【八】jqeury之click事件[添加及删除数据]

    要求:1.添加数据显示在下方列表.2.添加的数据可动态删除. 界面显示: 代码: <!DOCTYPE html> <html> <head> <script ...

  2. jQuery focus、blur事件 添加、删除类名

    jQuery.focusblur = function(ele,className){ var focusblurid = $(ele); focusblurid.focus(function(){ ...

  3. 原生js事件的添加和删除

    在IE浏览器中添加或删除事件用attachEvent.detachEvent.在其他标准浏览器中则用addEventListener.removeEventListener.下面的对事件的添加和删除做 ...

  4. jquery 添加与删除的规律 当要添加时候要定位到自己的父元素 当要删除时候 通过事件函数传入的this找到自己的父元素进行删除

    jquery 添加与删除的规律 当要添加时候要定位到自己的父元素  当要删除时候 通过事件函数传入的this找到自己的父元素进行删除

  5. 数组练习:各种数组方法的使用&&事件练习:封装兼容性添加、删除事件的函数&&星级评分系统

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. (三)根据向导创建MFC工程,事件的添加和删除

    一,文档视图结构 文档:它是一个类,这个类专门用来存储数据 视图:它是一个类,这个类专门用来显示和修改数据 框架类:一个容器,这个容器装了视图 健完工程之后,类视图: 运行一下: 几个比较重要的函数 ...

  7. 第一百七十一节,jQuery,高级事件,模拟操作,命名空间,事件委托,on、off 和 one

    jQuery,高级事件,模拟操作,命名空间,事件委托,on.off 和 one 学习要点: 1.模拟操作 2.命名空间 3.事件委托 4.on.off 和 one jQuery 不但封装了大量常用的事 ...

  8. JS数组方法汇总 array数组元素的添加和删除

    js数组元素的添加和删除一直比较迷惑,今天终于找到详细说明的资料了,先给个我测试的代码^-^ var arr = new Array(); arr[0] = "aaa"; arr[ ...

  9. jQuery实现动态添加和删除一个div

    本文主要给大家简单介绍一下如何动态的在一个元素添加和删除div,希望能够得到举一反三之效. 代码实例如下: <!DOCTYPE html> <html> <head> ...

随机推荐

  1. Python爬虫第一个成功版

    爬取http://www.mzitu.com/all里面的图片 import urllib.request import re import os url = 'http://www.mzitu.co ...

  2. python3中替换python2中cmp函数

    python 3.4.3 的版本中已经没有cmp函数,被operator模块代替,在交互模式下使用时,需要导入模块. 在没有导入模块情况下,会出现 提示找不到cmp函数了,那么在python3中该如何 ...

  3. testng入门教程7 TestNG组测试

    在TestNG中组测试是一个新的创新功能,它不存在于JUnit框架,它允许调度到适当的部分方法和瓶坯复杂的测试方法分组.您不仅可以声明属于群体的那些方法,但你也可以指定一组包含其他组.然后,TestN ...

  4. Log4net 日志传到 graylog监控

    graylog是java的一个日志监控插件.存储用的是mongoDB,效率还是挺高的.不过嘛,文档太少了,安装和配置都很不容易. 官网:http://www.graylog.org/ 在graylog ...

  5. JNDI—目录接口名

    1:什么是JNDI? Java名称与目录接口:java Naming and Directory Interface未开发人员提供的查找和访问各种名称和目录的 服务和接口 2:全局的上下文配置文件: ...

  6. font-awesome图标

  7. VC++文件操作之最全篇

    一.剖析VC中的文件操作 各种关于文件的操作在程序设计中是十分常见,如果能对其各种操作都了如指掌,就可以根据实际情况找到最佳的解决方案,从而在较短的时间内编写出高效的代码,因而熟练的掌握文件操作是十分 ...

  8. 【kafka学习之三】kafka集群运维

    kafka集群维护一.kafka集群启停#启动kafka/home/cluster/kafka211/bin/kafka-server-start.sh -daemon /home/cluster/k ...

  9. 隐马尔科夫模型(HMM)学习笔记二

    这里接着学习笔记一中的问题2,说实话问题2中的Baum-Welch算法编程时矩阵转换有点烧脑,开始编写一直不对(编程还不熟练hh),后面在纸上仔细推了一遍,由特例慢慢改写才运行成功,所以代码里面好多处 ...

  10. 隐马尔可夫模型(HMM)学习笔记一

    学习了李航的<统计学习方法>中隐马尔可夫模型(Hidden Markov Model, HMM),这里把自己对HMM的理解进行总结(大部分是书本原文,O(∩_∩)O哈哈~,主要是想利用py ...