从《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. PAT 1023 Have Fun with Numbers[大数乘法][一般]

    1023 Have Fun with Numbers (20)(20 分) Notice that the number 123456789 is a 9-digit number consistin ...

  2. 单利模式及python实现方式

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  3. 修改form 的字段背景颜色及字体颜色

    1.通过个性化实现 2. 修改form 代码 有一张工资单,当某个员工的工资超过5000时,用户需要系统能用红色来指示员工的姓名和工资. 实现方法: 我们新做一张form,按常规建好block和ite ...

  4. Geometry

    uva1473 这题说的是 在空间中给了n个点 然后用体积最小的圆锥将这些点包含在内可以在表面上, 将这些点 映射到xoz平面上然后,然后枚举每个上凸包的边和每个点的极值进行判断求得最小的体积 我们会 ...

  5. Intro to Python for Data Science Learning 6 - NumPy

    NumPy From:https://campus.datacamp.com/courses/intro-to-python-for-data-science/chapter-4-numpy?ex=1 ...

  6. Java基础语法(基本语句)

    Java基础语法 标识符在程序中自定义的一些名称.由26个英文字母大小写,数字:0-9符号:_&组成定义合法标识符规则:1.      数字不可以开头2.      不可以使用关键字Java中 ...

  7. 【转】Redis之发布 订阅模式

    本例包括 jedis_demo:入口类 jedis_control:jedis控制器(jedis的连接池) jedis_pub_sub_listener:订阅的监听器 singleton_agent: ...

  8. python requests 请求的封装

    #encoding=utf-8import requestsimport jsonclass HttpClient(object):    def __init__(self):        pas ...

  9. Linux基础命令---unzip

    unzip 解压zip指令压缩过的文件.unzip将列出.测试或从ZIP存档中提取文件,这些文件通常在MS-DOS系统中找到.默认行为(没有选项)是将指定ZIP存档中的所有文件提取到当前目录(及其下面 ...

  10. Linux笔记 #07# 搭建机器学习环境

    环境: Debian 8.8 64位, 同样适用 win10 基本步骤: 安装 Python 安装必要的库 测试 一.安装 Python 延续之前的 搭建 Python 环境 选取折中版本 Pytho ...