从《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. [py][mx]django xadmin后台配置

    xadmin配置 - 安装 pip install -r https://github.com/sshwsfc/xadmin/blob/django2/requirements.txt 以下被我测试通 ...

  2. [svc]ftp协议数据连接的2种模式

    玩明白了以太网2的二层数据格式, ip格式 tcp/udp个时候, 需要玩一玩一些有用的基于这些已上的协议数据了. 如 dhcp ftp等.比较有趣. ftp协议 分控制连接21端口 和数据连接 20 ...

  3. Python安装常见问题(1):zipimport.ZipImportError: can't decompress data

    在CentOS以及其他的Linux系统中遇到安装包安装错误的原因,大多数都是因为缺少依赖包导致的,所以对于错误:zipimport.ZipImportError: can’t decompress d ...

  4. Fiddler过滤指定域名

    Fiddler过滤指定域名的方法一 切换到fiddler右侧窗口的Filters选项卡,勾选顶部的“Use Filters”,找到Hosts区域,设置以下三个选项: 1.第一项有三个选项,不做更改: ...

  5. ZOJ 3949 Edge to the Root

    题意: 在一棵树中,可以从根节点往其他节点加一条边,使得根节点到其他所有节点的距离和最小,输出最小的距离和. 思路: 我们考虑在加的一条边为$1 \to v$,那么在树上从$1 \to v$的路径上, ...

  6. hdu6000 Wash ccpc-20162017-finals B Wash

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6000 题目: Wash Time Limit: 20000/10000 MS (Java/Ot ...

  7. EOJ Monthly 2018.11 猜价格 (模拟)

    分三种情况: 1.k=1.此时每次都说反话,反着二分即可. 2.1<k <= n.那么在前n次问答中一定会出现一次错误,通过不断输出1找出那个错误发生的位置(若回答是>那这就是错误) ...

  8. zw版【转发·台湾nvp系列Delphi例程】HALCON HistoToThresh1

    zw版[转发·台湾nvp系列Delphi例程]HALCON HistoToThresh1 procedure TForm1.Button1Click(Sender: TObject);var imag ...

  9. 527D Clique Problem 判断一维线段没有两辆相交的最大线段数量

    这题说的是给了n个位置 在x轴上 每个位置有一个权值为wi,然后将|xi - xj|>=wi+wj ,满足这个条件的点建一条边,计算着整张图中有多少多少个点构成的子图,使得这个子图的节点数尽量的 ...

  10. EditPlus 4.3.2555 中文版已经发布

    新的版本修复了之前版本出现的多行文本缩进调整的问题. 下载连接在页面左上角!