private static Delegate CreateMethod(Type delegateType, Type returnType, Type[] parameterTypes, params Expression[] expressions) { var method = new DynamicMethod("testMethod", returnType, parameterTypes, typeof(BuilderTestBase), true); var builder = new MethodBodyBuilder(method, parameterTypes).AddStatements(expressions); Console.WriteLine(builder); builder.Compile(); return(method.CreateDelegate(delegateType)); }
static void Main(string[] args) { var asmName = "PlayGround.Generated"; var fileName = "PlayGround.Generated.dll"; var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(asmName), AssemblyBuilderAccess.RunAndSave); var modBuilder = asmBuilder.DefineDynamicModule(asmName, fileName, true); var typeBuilder = modBuilder.DefineType("PlayGround.Generated.MyClass", TypeAttributes.Class | TypeAttributes.Public); var fieldBuilder = typeBuilder.DefineField("field", typeof(string), FieldAttributes.InitOnly | FieldAttributes.Static | FieldAttributes.Public); var cb = typeBuilder.DefineTypeInitializer(); var builder = new MethodBodyBuilder(cb); builder.AddStatements( Expr.WriteField(fieldBuilder, Expr.Constant("abc")), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("Hello my friend!")), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }), Expr.Constant("What a {0} day!"), Expr.Constant("beautiful")), Expr.Call(typeof(Console).GetMethod("ReadKey", new Type[0]))); Console.WriteLine(builder.ToString()); builder.Compile(); var mb = typeBuilder.DefineMethod("foo", MethodAttributes.Public); mb.SetReturnType(typeof(string)); mb.SetParameters(typeof(int)); mb.DefineParameter(1, ParameterAttributes.None, "val"); builder = new MethodBodyBuilder(mb, typeof(int)); builder.AddStatements( Expr.IfThen(Expr.Parameter(1, typeof(int)), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("aha!"))), Expr.Return(Expr.Call( Expr.Call( Expr.New(typeof(StringBuilder)), typeof(StringBuilder).GetMethod("AppendFormat", new[] { typeof(string), typeof(object), typeof(object) }), Expr.Constant("{0}_{1}"), Expr.ReadField(fieldBuilder), Expr.Convert(Expr.Parameter(1, typeof(int)), typeof(object))), typeof(StringBuilder).GetMethod("ToString", new Type[0])))); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("bar", MethodAttributes.Public); mb.SetReturnType(typeof(string)); mb.SetParameters(typeof(string)); mb.DefineParameter(1, ParameterAttributes.None, "text"); builder = new MethodBodyBuilder(mb, typeof(string)); builder.AddStatements( Expr.Return( Expr.Call(typeof(string).GetMethod("Format", new[] { typeof(string), typeof(object), typeof(object) }), Expr.Constant("Result: {0}-{1}"), Expr.IfThenElse( Expr.Parameter(1, typeof(string)), Expr.Call(typeof(string).GetMethod("Format", new[] { typeof(string), typeof(object) }), Expr.Constant("Date: {0}"), Expr.Convert(Expr.Parameter(1, typeof(string)), typeof(object))), Expr.Constant("Undefined!")), Expr.Convert(Expr.Convert(Expr.Convert(Expr.Constant(16), typeof(object)), typeof(int)), typeof(object))) )); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("tryFinally", MethodAttributes.Public); mb.SetParameters(typeof(string)); mb.SetReturnType(typeof(void)); mb.DefineParameter(1, ParameterAttributes.None, "value"); builder = new MethodBodyBuilder(mb, typeof(string)); builder.AddStatements( Expr.TryFinally( Expr.IfThenElse(Expr.Parameter(1, typeof(string)), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Parameter(1, typeof(string))), Expr.Throw(Expr.New(typeof(Exception), Expr.Constant("No string provided!")))), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("finally!"))) ); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("tryCatchFinally", MethodAttributes.Public); mb.SetParameters(typeof(string)); mb.SetReturnType(typeof(void)); mb.DefineParameter(1, ParameterAttributes.None, "value"); builder = new MethodBodyBuilder(mb, typeof(string)); var loc1 = Expr.LocalVariable(typeof(Exception), "e"); builder.AddStatements( Expr.TryCatchFinally( Expr.IfThenElse(Expr.Parameter(1, typeof(string)), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Parameter(1, typeof(string))), Expr.Throw(Expr.New(typeof(ArgumentNullException), Expr.Constant("No string provided!")))), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("finally!")), new CatchBlock(typeof(ArgumentNullException), loc1, Expr.Rethrow()) )); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("localVar", MethodAttributes.Public); mb.SetReturnType(typeof(void)); var var1 = Expr.LocalVariable(typeof(string), "o"); var var2 = Expr.LocalVariable(typeof(int), "i"); builder = new MethodBodyBuilder(mb, typeof(string)); builder.AddStatements( Expr.DeclareLocal(var1, Expr.Constant("High {0}!")), Expr.DeclareLocal(var2, Expr.Constant(5)), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string), typeof(object) }), Expr.ReadLocal(var1), Expr.Convert(Expr.ReadLocal(var2), typeof(object)))); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("negNot", MethodAttributes.Public); mb.SetReturnType(typeof(int)); mb.SetParameters(typeof(byte)); builder = new MethodBodyBuilder(mb, typeof(byte)); builder.AddStatements(Expr.Return(Expr.Not(Expr.Negate(Expr.Parameter(1, typeof(byte)))))); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("loop", MethodAttributes.Public); mb.SetReturnType(typeof(void)); var iVar = Expr.LocalVariable(typeof(int), "i"); builder = new MethodBodyBuilder(mb); builder.AddStatements( Expr.DeclareLocal(iVar, Expr.Constant(10)), Expr.Loop(Expr.IfThenElse( Expr.ReadLocal(iVar), Expr.Block( Expr.WriteLocal(iVar, Expr.Add(Expr.ReadLocal(iVar), Expr.Constant(-1))), Expr.Call(typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }), Expr.Constant("loop!..."))), Expr.LoopBreak())) ); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("conv", MethodAttributes.Public); mb.SetReturnType(typeof(ulong)); builder = new MethodBodyBuilder(mb); builder.AddStatements(Expr.Return(Expr.Convert(Expr.Constant(-1), typeof(ulong)))); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("intTS", MethodAttributes.Public); mb.SetReturnType(typeof(string)); builder = new MethodBodyBuilder(mb); builder.AddStatements(Expr.Return(Expr.Call(Expr.Constant(21), typeof(int).GetMethod("ToString", new Type[0])))); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("loadStructField", MethodAttributes.Public); mb.SetParameters(typeof(MyStruct)); mb.SetReturnType(typeof(string)); builder = new MethodBodyBuilder(mb, typeof(MyStruct)); builder.AddStatements(Expr.Return(Expr.ReadField(Expr.Parameter(1, typeof(MyStruct)), typeof(MyStruct).GetField("MyField")))); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("saveStructField", MethodAttributes.Public); mb.SetParameters(typeof(MyStruct), typeof(string)); mb.SetReturnType(typeof(MyStruct)); builder = new MethodBodyBuilder(mb, typeof(MyStruct), typeof(string)); builder.AddStatements( Expr.WriteField(Expr.Parameter(1, typeof(MyStruct)), typeof(MyStruct).GetField("MyField"), Expr.Parameter(2, typeof(string))), Expr.Return(Expr.Parameter(1, typeof(MyStruct)))); Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("createStruct", MethodAttributes.Public); mb.SetReturnType(typeof(MyStruct)); builder = new MethodBodyBuilder(mb, typeof(MyStruct), typeof(string)); builder.AddStatements(Expr.Return(Expr.New(typeof(MyStruct))));//, Expr.Constant(32L), Expr.Constant("abcd") Console.WriteLine(builder.ToString()); builder.Compile(); mb = typeBuilder.DefineMethod("catchException", MethodAttributes.Public); mb.SetReturnType(typeof(Exception)); builder = new MethodBodyBuilder(mb); var local = Expr.LocalVariable(typeof(Exception), "e"); builder.AddStatements( Expr.DeclareLocal(local), Expr.TryCatch( Expr.Throw(Expr.New(typeof(InvalidOperationException), Expr.Constant("abc"))), new CatchBlock(typeof(InvalidOperationException), local, false, Expr.Empty())), Expr.Return(Expr.ReadLocal(local))); Console.WriteLine(builder.ToString()); builder.Compile(); typeBuilder.CreateType(); asmBuilder.Save(fileName); }