// example based on the MSDN Events Sample (events1.cs) public static void GenEvents1(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; ITypeMapper m = ag.TypeMapper; TypeGen ChangedEventHandler, ListWithChangedEvent; using (ag.Namespace("MyCollections")) { // A delegate type for hooking up change notifications. ChangedEventHandler = ag.Delegate(typeof(void), "ChangedEventHandler").Parameter(typeof(object), "sender").Parameter(typeof(EventArgs), "e"); // A class that works just like ArrayList, but sends event // notifications whenever the list changes. ListWithChangedEvent = ag.Public.Class("ListWithChangedEvent", typeof(ArrayList)); { // An event that clients can use to be notified whenever the // elements of the list change. EventGen Changed = ListWithChangedEvent.Public.Event(ChangedEventHandler, "Changed"); // Invoke the Changed event; called whenever list changes CodeGen g = ListWithChangedEvent.Protected.Virtual.Method(typeof(void), "OnChanged").Parameter(typeof(EventArgs), "e"); { g.If(Changed != null); { g.InvokeDelegate(Changed, g.This(), g.Arg("e")); } g.End(); } // Override some of the methods that can change the list; // invoke event after each g = ListWithChangedEvent.Public.Override.Method(typeof(int), "Add").Parameter(typeof(object), "value"); { var i = g.Local(g.Base().Invoke("Add", new[] { g.Arg("value") })); g.Invoke(g.This(), "OnChanged", st.Field(typeof(EventArgs), "Empty")); g.Return(i); } g = ListWithChangedEvent.Public.Override.Method(typeof(void), "Clear"); { g.Invoke(g.Base(), "Clear"); g.Invoke(g.This(), "OnChanged", st.Field(typeof(EventArgs), "Empty")); } g = ListWithChangedEvent.Public.Override.Indexer(typeof(object)).Index(typeof(int), "index").Setter(); { g.Assign(g.Base()[g.Arg("index")], g.PropertyValue()); g.Invoke(g.This(), "OnChanged", st.Field(typeof(EventArgs), "Empty")); } } } using (ag.Namespace("TestEvents")) { TypeGen EventListener = ag.Class("EventListener"); { FieldGen List = EventListener.Field(ListWithChangedEvent, "List"); // This will be called whenever the list changes. CodeGen g = EventListener.Private.Method(typeof(void), "ListChanged").Parameter(typeof(object), "sender").Parameter(typeof(EventArgs), "eventArgs"); { g.WriteLine("This is called when the event fires."); } g = EventListener.Public.Constructor().Parameter(ListWithChangedEvent, "list"); { g.Assign(List, g.Arg("list")); // Add "ListChanged" to the Changed event on "List". g.SubscribeEvent(List, "Changed", exp.NewDelegate(ChangedEventHandler, g.This(), "ListChanged")); } g = EventListener.Public.Method(typeof(void), "Detach"); { // Detach the event and delete the list g.UnsubscribeEvent(List, "Changed", exp.NewDelegate(ChangedEventHandler, g.This(), "ListChanged")); g.Assign(List, null); } } TypeGen Test = ag.Class("Test"); { // Test the ListWithChangedEvent class. CodeGen g = Test.Public.Static.Method(typeof(void), "Main"); { // Create a new list. var list = g.Local(exp.New(ListWithChangedEvent)); // Create a class that listens to the list's change event. var listener = g.Local(exp.New(EventListener, list)); // Add and remove items from the list. g.Invoke(list, "Add", "item 1"); g.Invoke(list, "Clear"); g.Invoke(listener, "Detach"); } } } }
// example based on the MSDN Delegates Sample (compose.cs) public static void GenCompose(AssemblyGen ag) { var st = ag.StaticFactory; var exp = ag.ExpressionFactory; TypeGen myDelegate = ag.Delegate(typeof(void), "MyDelegate").Parameter(typeof(string), "string"); TypeGen myClass = ag.Class("MyClass"); { CodeGen g = myClass.Public.Static.Method(typeof(void), "Hello").Parameter(typeof(string), "s"); { g.WriteLine(" Hello, {0}!", g.Arg("s")); } g = myClass.Public.Static.Method(typeof(void), "Goodbye").Parameter(typeof(string), "s"); { g.WriteLine(" Goodbye, {0}!", g.Arg("s")); } g = myClass.Public.Static.Method(typeof(void), "Main"); { ContextualOperand a = g.Local(), b = g.Local(), c = g.Local(), d = g.Local(); // Create the delegate object a that references // the method Hello: ITypeMapper typeMapper = ag.TypeMapper; g.Assign(a, exp.NewDelegate(myDelegate, myClass, "Hello")); // Create the delegate object b that references // the method Goodbye: ITypeMapper typeMapper1 = ag.TypeMapper; g.Assign(b, exp.NewDelegate(myDelegate, myClass, "Goodbye")); // The two delegates, a and b, are composed to form c, // which calls both methods in order: g.Assign(c, a + b); // Remove a from the composed delegate, leaving d, // which calls only the method Goodbye: g.Assign(d, c - a); g.WriteLine("Invoking delegate a:"); g.InvokeDelegate(a, "A"); g.WriteLine("Invoking delegate b:"); g.InvokeDelegate(b, "B"); g.WriteLine("Invoking delegate c:"); g.InvokeDelegate(c, "C"); g.WriteLine("Invoking delegate d:"); g.InvokeDelegate(d, "D"); } } }