title: C# Creating an Event System with delegates
body: <p>I am making a game using Unity and creating a simple event system for it. The system allows subscribing to events with a callback delegate.</p>
  
  <p>The code for the system is here:</p>
  
  <pre><code>public static class Events {
  
  #region fields
  public delegate void EventCallback();
  
  public static Dictionary&lt;Event, EventCallback&gt; events;
  
  public enum Event {
      PlayerDied,
      EnterGoal,
      ExitGoal
  }
  #endregion
  
  static Events() {
      Reset();
  }
  
  public static void Reset() {
      events = new Dictionary&lt;Event, EventCallback&gt;();
  }
  
  public static void SubscribeToEvent(EventCallback callback, Event type) {
  
      if (!events.ContainsKey(type)) {
          events.Add(type, callback);
      } else {
          events[type] += callback;
      }
  }
  
  public static void OverrideSubscription(EventCallback callback, Event type) {
  
      if (!events.ContainsKey(type)) {
          events.Add(type, callback);
      } else {
          events[type] = callback;
      }
  }
  public static void UnsubscribeFromEvent(EventCallback callback, Event type) {
      if (events.ContainsKey(type)) {
          events[type] -= callback;
      }
  }
  
  public static void FireEvent(Event type) {
  
      if (!events.ContainsKey(type)) {
          return;
      }
  
      events[type]?.Invoke();
  }
  }
  </code></pre>
  
  <p>My problem is this: </p>
  
  <p>Quite often in the game the object which subscribes to some event will be destroyed  (and therefore nullified) but the callbacks are still called.</p>
  
  <p>To demonstrate this I created tests for it. The 2 tests below fail.</p>
  
  <pre><code>[Test]
      public void CallbackIsNotCalledAfterReassigning() {
  
          Events.SubscribeToEvent(callbacks.A, Events.Event.PlayerDied);
  
          // Reassign
          callbacks = new CallbackContainer();
  
          Events.FireEvent(Events.Event.PlayerDied);
  
          Assert.AreEqual(0, callbacks.a, "Test function was called after reassigning");
          Assert.AreEqual(0, a, "Old instance method is still being called");
      }
  
      [Test]
      public void CallbackIsNotCalledAfterNullifying() {
  
          Events.SubscribeToEvent(callbacks.A, Events.Event.PlayerDied);
  
          // Nullify
          callbacks = null;
  
          Events.FireEvent(Events.Event.PlayerDied);
  
          Assert.AreEqual(0, a, "Test function was not called");
      }
  </code></pre>
  
  <p>And the CallbackContainer class is here:</p>
  
  <pre><code>public class CallbackContainer {
  
      public int a, b, c;
  
      public CallbackContainer() {
          int a = 0;
          int b = 0;
          int c = 0;
      }
  
      public Action TestFunction;
  
      public void A() {
          EventsTest.a++;
          a++;
      }
      public void B() {
          EventsTest.b++;
          b++;
      }
      public void C() {
          EventsTest.c++;
          c++;
      }
  }
  </code></pre>
  
  <p>Is there a workaround for this problem? Is there a better and more correct way to creating an event system?</p>
  
  <p>Any help or advice is appreciated.</p>