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>
public event Action<T> ChangeValue = delegate {};
private Dictionary<System.Action<object>, List<System.Action<T>>> ObjectEventProxies
= new Dictionary<System.Action<object>, List<System.Action<T>>>();
public event System.Action<object> ChangeObject
List<System.Action<T>> eventProxies;
if(!ObjectEventProxies.TryGetValue(value, out eventProxies))
eventProxies = new List<System.Action<T>>();
ObjectEventProxies.Add(value, eventProxies);
System.Action<T> proxy = (T v) => value.Invoke(v);
List<System.Action<T>> eventProxies;
if (ObjectEventProxies.TryGetValue(value, out eventProxies))
System.Action<T> proxy = eventProxies[eventProxies.Count - 1];
eventProxies.RemoveAt(eventProxies.Count - 1);
private Dictionary<System.Action, List<System.Action<T>>> EmptyEventProxies
= new Dictionary<System.Action, List<System.Action<T>>>();
public event System.Action ChangeEmpty
List<System.Action<T>> eventProxies;
if(!EmptyEventProxies.TryGetValue(value, out eventProxies))
eventProxies = new List<System.Action<T>>();
EmptyEventProxies.Add(value, eventProxies);
System.Action<T> newProxy = (T v) => value.Invoke();
eventProxies.Add(newProxy);
List<System.Action<T>> eventProxies;
if (EmptyEventProxies.TryGetValue(value, out eventProxies))
System.Action<T> proxy = eventProxies[eventProxies.Count - 1];
eventProxies.RemoveAt(eventProxies.Count - 1);
public void InvokeChange(T value)
ChangeValue.Invoke(value);