Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do C# Events work behind the scenes?
    text
    copied!<p>I'm using C#, .NET 3.5. I understand how to utilize events, how to declare them in my class, how to hook them from somewhere else, etc. A contrived example:</p> <pre><code>public class MyList { private List&lt;string&gt; m_Strings = new List&lt;string&gt;(); public EventHandler&lt;EventArgs&gt; ElementAddedEvent; public void Add(string value) { m_Strings.Add(value); if (ElementAddedEvent != null) ElementAddedEvent(value, EventArgs.Empty); } } [TestClass] public class TestMyList { private bool m_Fired = false; [TestMethod] public void TestEvents() { MyList tmp = new MyList(); tmp.ElementAddedEvent += new EventHandler&lt;EventArgs&gt;(Fired); tmp.Add("test"); Assert.IsTrue(m_Fired); } private void Fired(object sender, EventArgs args) { m_Fired = true; } } </code></pre> <p>However, what I do <em>not</em> understand, is when one declares an event handler</p> <pre><code>public EventHandler&lt;EventArgs&gt; ElementAddedEvent; </code></pre> <p>It's never initialized - so what, exactly, is ElementAddedEvent? What does it point to? The following won't work, because the EventHandler is never initialized:</p> <pre><code>[TestClass] public class TestMyList { private bool m_Fired = false; [TestMethod] public void TestEvents() { EventHandler&lt;EventArgs&gt; somethingHappend; somethingHappend += new EventHandler&lt;EventArgs&gt;(Fired); somethingHappend(this, EventArgs.Empty); Assert.IsTrue(m_Fired); } private void Fired(object sender, EventArgs args) { m_Fired = true; } } </code></pre> <p>I notice that there is an EventHandler.CreateDelegate(...), but all the method signatures suggest this is only used for attaching Delegates to an already existing EventHandler through the typical ElementAddedEvent += new EventHandler(MyMethod).</p> <p>I'm not sure if <em>what</em> I am trying to do will help... but ultimately I'd like to come up with an abstract parent DataContext in LINQ whose children can register which table Types they want "observed" so I can have events such as BeforeUpdate and AfterUpdate, but specific to types. Something like this:</p> <pre><code>public class BaseDataContext : DataContext { private static Dictionary&lt;Type, Dictionary&lt;ChangeAction, EventHandler&gt;&gt; m_ObservedTypes = new Dictionary&lt;Type, Dictionary&lt;ChangeAction, EventHandler&gt;&gt;(); public static void Observe(Type type) { if (m_ObservedTypes.ContainsKey(type) == false) { m_ObservedTypes.Add(type, new Dictionary&lt;ChangeAction, EventHandler&gt;()); EventHandler eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler; m_ObservedTypes[type].Add(ChangeAction.Insert, eventHandler); eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler; m_ObservedTypes[type].Add(ChangeAction.Update, eventHandler); eventHandler = EventHandler.CreateDelegate(typeof(EventHandler), null, null) as EventHandler; m_ObservedTypes[type].Add(ChangeAction.Delete, eventHandler); } } public static Dictionary&lt;Type, Dictionary&lt;ChangeAction, EventHandler&gt;&gt; Events { get { return m_ObservedTypes; } } } public class MyClass { public MyClass() { BaseDataContext.Events[typeof(User)][ChangeAction.Update] += new EventHandler(OnUserUpdate); } public void OnUserUpdated(object sender, EventArgs args) { // do something } } </code></pre> <p>Thinking about this made me realize I don't really understand what's happening under the hod with events - and I would like to understand :)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload