using System.Collections.Generic;
event Action<T> ChangeValue;
event Action<object> ChangeObject;
event Action ChangeEmpty;
void InvokeChange(T value);
public static void Main()
IFoo<int> test1 = new Foo<int>();
test1.ChangeEmpty += () => Console.WriteLine("0) Empty!");
test1.ChangeObject += (o) => Console.WriteLine("1) Object: {0}", o);
test1.ChangeValue += (v) => Console.WriteLine("2) Value: {0}", v);
test1.ChangeObject += (o) => Console.WriteLine("3) Object: {0}", o);
test1.ChangeEmpty += () => Console.WriteLine("4) Empty!");
Console.WriteLine("\n--------\n");
IFoo<int> test2 = new Foo<int>();
test2.ChangeEmpty += EmptyHandler;
test2.ChangeObject += ObjectHandler;
Console.WriteLine("1) EMPTY, OBJECT");
test2.ChangeEmpty -= EmptyHandler;
test2.ChangeValue += ValueHandler;
Console.WriteLine("2) OBJECT, VALUE");
test2.ChangeObject -= ObjectHandler;
Console.WriteLine("3) VALUE ");
test2.ChangeObject += ObjectHandler;
test2.ChangeEmpty += EmptyHandler;
test2.ChangeValue += ValueHandler;
Console.WriteLine("4) VALUE, OBJECT, EMPTY, VALUE");
test2.ChangeValue -= ValueHandler;
test2.ChangeValue -= ValueHandler;
test2.ChangeEmpty -= EmptyHandler;
test2.ChangeObject -= ObjectHandler;
Console.WriteLine("5) <NONE>");
static void EmptyHandler() { Console.WriteLine(" - Empty!"); }
static void ObjectHandler(object val) { Console.WriteLine(" - Object: {0}", val); }
static void ValueHandler(int val) { Console.WriteLine(" - Value: {0}", val); }
public class Foo<T> : IFoo<T>
private EventProxyContainer<T> handlers;
public event Action<T> ChangeValue
add { handlers.Add(value); }
remove { handlers.Remove(value); }
public event Action<object> ChangeObject
add { handlers.Add(value); }
remove { handlers.Remove(value); }
public event Action ChangeEmpty
add { handlers.Add(value); }
remove { handlers.Remove(value); }
public void InvokeChange(T value)
foreach(Action<T> a in handlers.GetInvocationList())
public struct EventProxyContainer<T>
private event Action<T> handlers;
private struct EventProxy
private Dictionary<object, EventProxy> proxies;
public void Add(object handler)
if(handler == null) return;
if(proxies == null) proxies = new Dictionary<object, EventProxy>();
if(proxies.TryGetValue(handler, out entry))
proxies[handler] = entry;
entry = new EventProxy() { count = 1 };
entry.proxy = (Action<T>)handler;
else if(handler is Action<object>)
entry.proxy = (v) => ((Action<object>)handler).Invoke(v);
else if (handler is Action)
entry.proxy = (v) => ((Action)handler).Invoke();
proxies.Add(handler, entry);
public void Remove(object handler)
if(handler == null || proxies == null) return;
if(proxies.TryGetValue(handler, out entry))
proxies[handler] = entry;
public Delegate[] GetInvocationList()
return handlers == null ? new Delegate[0] : handlers.GetInvocationList();