using System; using System.Collections.Generic; using System.Reflection; namespace DelegateHacking { class EventClass { public event EventHandler MyEvent; public void Fire() { if (this.MyEvent != null) { MyEvent(this, new EventArgs()); } } } class A { public A(EventClass e) { e.MyEvent += new EventHandler(e_MyEvent); } void e_MyEvent(object sender, EventArgs e) { System.Console.WriteLine("A: Method called"); } } class B { public B(EventClass e) { e.MyEvent += new EventHandler(e_MyEvent); } void e_MyEvent(object sender, EventArgs e) { System.Console.WriteLine("B: Method called"); } } class Program { static void Main(string[] args) { // Create a class to fire events EventClass evt = new EventClass(); // Create some consumers and attach them to the eventing class A a1 = new A(evt); B b1 = new B(evt); A a2 = new A(evt); B b2 = new B(evt); // See the behaviour before manipulation Console.WriteLine("Before manipulation"); evt.Fire(); // Get the type for the eventing class Type t = evt.GetType(); // The following code details some reflected information about the event class // if you are interested /* foreach (MemberInfo m in t.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public)) { Console.Write(m.MemberType.ToString()); Console.Write(" : "); Console.WriteLine(m.Name); if (m.MemberType == MemberTypes.Field) { FieldInfo x = m as FieldInfo; Console.WriteLine(x.FieldType.FullName); Console.WriteLine(x.FieldType.BaseType.FullName); } if (m.MemberType == MemberTypes.Event) { EventInfo e = m as EventInfo; Console.WriteLine(e.EventHandlerType.FullName); } } */ // Get the private field for the event FieldInfo f = t.GetField("MyEvent", BindingFlags.Instance | BindingFlags.NonPublic); // Manipulate the field object evtValue = f.GetValue(evt); if (evtValue != null) { System.MulticastDelegate evtDelegate = evtValue as System.MulticastDelegate; Delegate[] delList = evtDelegate.GetInvocationList(); List targetList = new List(); foreach (Delegate d in delList) { if (d.Method.ReflectedType.FullName == "DelegateHacking.A") continue; targetList.Add(d); } Delegate target = MulticastDelegate.Combine(targetList.ToArray()); f.SetValue(evt, target); } // Repeat the test Console.WriteLine("After manipulation"); evt.Fire(); Console.ReadKey(); } } }