模拟C#的事件添加和删除

从《C# Via CLR》中的演化的一个小demo,探索事件的添加和删除原理,简单明了:

  1 using System;

  2 using System.Collections.Generic;

  3 using System.Linq;

  4 using System.Text;

  5 using System.Threading;

  6 using System.Threading.Tasks;

  7 

  8 namespace ExpForEvent001

  9 {

 10     public sealed class EventKey : Object { }

 11 

 12     public sealed class EventSet

 13     {

 14         private readonly Dictionary<EventKey, Delegate> m_events = new Dictionary<EventKey, Delegate>();

 15 

 16         public void Add(EventKey eventKey, Delegate handler)

 17         {

 18             Monitor.Enter(m_events);

 19             Delegate d;

 20             m_events.TryGetValue(eventKey, out d);

 21             m_events[eventKey] = Delegate.Combine(d, handler);//Here we used Combine

 22             Monitor.Exit(m_events);

 23         }

 24 

 25         public void Remove(EventKey eventKey, Delegate handler)

 26         {

 27             Monitor.Enter(m_events);

 28             Delegate d;

 29             if (m_events.TryGetValue(eventKey, out d))

 30             {

 31                 d = Delegate.Remove(d, handler);

 32 

 33                 if (d != null) m_events[eventKey] = d;

 34                 else m_events.Remove(eventKey);

 35             }

 36             Monitor.Exit(m_events);

 37         }

 38 

 39         public void Raise(EventKey eventKey, Object sender, EventArgs e)

 40         {

 41             Delegate d;

 42             Monitor.Enter(m_events);

 43             m_events.TryGetValue(eventKey, out d);

 44             Monitor.Exit(m_events);

 45 

 46             if (d != null)

 47             {

 48                 d.DynamicInvoke(new Object[]{ sender, e });

 49             }

 50         }

 51     }

 52 

 53     public class FooEventArgs : EventArgs { }

 54 

 55     public class TypeWithLotsOfEvents

 56     {

 57         public readonly EventSet m_eventSet = new EventSet();

 58 

 59         protected EventSet EventSet { get { return m_eventSet; } }

 60 

 61         #region Support Foo Event

 62 

 63         protected static readonly EventKey s_fooEventKey = new EventKey();

 64 

 65         public event EventHandler<FooEventArgs> Foo

 66         {

 67             add { m_eventSet.Add(s_fooEventKey, value); }

 68             remove { m_eventSet.Remove(s_fooEventKey, value); }

 69         }

 70 

 71         protected virtual void OnFoo(FooEventArgs e)

 72         {

 73             m_eventSet.Raise(s_fooEventKey, this, e);

 74         }

 75 

 76         public void SimulateFoo() { OnFoo(new FooEventArgs()); }

 77 

 78         #endregion

 79     }

 80 

 81     class Program

 82     {

 83         static void Main(string[] args)

 84         {

 85             TypeWithLotsOfEvents twle = new TypeWithLotsOfEvents();

 86 

 87             twle.Foo += HandleFooEvent1;

 88             twle.Foo += HandleFooEvent2;

 89 

 90             twle.SimulateFoo();

 91         }

 92 

 93         private static void HandleFooEvent1(object sender, FooEventArgs e)

 94         {

 95             Console.WriteLine("Handling Foo Event here...");

 96         }

 97 

 98         private static void HandleFooEvent2(object sender, FooEventArgs e)

 99         {

100             Console.WriteLine("Handling Foo Event here2...");

101         }

102     }

103 }
View Code

 

运行结果:

 

附带Richter大神的一段话:

“JIT编译器能判断代码是否运行在一个Intel Pentium 4 CPU上,并生成相应的本地代码来利用Pentium 4支持的任何【特殊】指令,相反,非托管代码通常是针对通用的、具有最小功能集合的CPU编译的,不会使用提升应用程序性能的特殊指令。”

My words:

不同的体系结构的计算机其指令集是有差别的。软件越抽象则离硬件越远,从而阻挡了我们看到问题实质的视野。

你可能感兴趣的:(C#)