using System; using System.Collections.Generic; public delegate void EventHandler1(int i); public delegate void EventHandler2(string s); public class PropertyEventsSample { private readonly Dictionary‹string, Delegate› _eventTable; private readonly List‹EventHandler1› _event1List = new List‹EventHandler1›(); private readonly List‹EventHandler2› _event2List = new List‹EventHandler2›(); public PropertyEventsSample() { _eventTable = new Dictionary‹string, Delegate› { {"Event1", null}, {"Event2", null} }; } public event EventHandler1 Event1 { add { _event1List.Add(value); lock (_eventTable) { _eventTable["Event1"] = (EventHandler1) _eventTable["Event1"] + value; } } remove { if (!_event1List.Contains(value)) return; _event1List.Remove(value); lock (_eventTable) { _eventTable["Event1"] = null; foreach (var event1 in _event1List) { _eventTable["Event1"] = (EventHandler1) _eventTable["Event1"] + event1; } } } } public event EventHandler2 Event2 { add { _event2List.Add(value); lock (_eventTable) { _eventTable["Event2"] = (EventHandler2) _eventTable["Event2"] + value; } } remove { if (!_event2List.Contains(value)) return; _event2List.Remove(value); lock (_eventTable) { _eventTable["Event2"] = null; foreach (var event2 in _event2List) { _eventTable["Event2"] = (EventHandler2) _eventTable["Event2"] + event2; } } } } internal void RaiseEvent1(int i) { lock (_eventTable) { var handler1 = (EventHandler1) _eventTable["Event1"]; handler1?.Invoke(i); } } internal void RaiseEvent2(string s) { lock (_eventTable) { var handler2 = (EventHandler2) _eventTable["Event2"]; handler2?.Invoke(s); } } } public static class TestClass { private static void Delegate1Method(int i) { Console.WriteLine(i); } private static void Delegate2Method(string s) { Console.WriteLine(s); } private static void Main() { var p = new PropertyEventsSample(); p.Event1 += Delegate1Method; p.Event1 += Delegate1Method; p.Event1 -= Delegate1Method; p.RaiseEvent1(2); p.Event2 += Delegate2Method; p.Event2 += Delegate2Method; p.Event2 -= Delegate2Method; p.RaiseEvent2("TestString"); // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); } } /* Output: 2 TestString */