// // ALL SOURCE CODE IS PROVIDED AS IS, WITH NO WARRANTIES INTENDED OR IMPLIED. USE AT YOUR OWN RISK. // // Sample code for "ILGenerator.EmitCall is mainly for vararg methods" (blogs.msdn.com/haibo_luo) // using System; using System.Reflection; using System.Reflection.Emit; public class Demo { public static void VarargMethod(string headline, __arglist) { ArgIterator ai = new ArgIterator(__arglist); Console.Write(headline); while (ai.GetRemainingCount() > 0) Console.Write(TypedReference.ToObject(ai.GetNextArg())); Console.WriteLine(); } static void CallVarargMethod() { VarargMethod("Hello world from ", __arglist(Assembly.GetExecutingAssembly())); VarargMethod("Current time: ", __arglist(DateTime.Now, " (UTC ", DateTime.UtcNow, ")")); } static void EmitCode(ILGenerator il) { MethodInfo miVarargMethod = typeof(Demo).GetMethod("VarargMethod"); il.Emit(OpCodes.Ldstr, "Hello world from "); il.Emit(OpCodes.Call, typeof(Assembly).GetMethod("GetExecutingAssembly")); il.EmitCall(OpCodes.Call, miVarargMethod, new Type[] { typeof(Assembly) }); il.Emit(OpCodes.Ldstr, "Current time: "); il.Emit(OpCodes.Call, typeof(DateTime).GetMethod("get_Now")); il.Emit(OpCodes.Ldstr, " (UTC "); il.Emit(OpCodes.Call, typeof(DateTime).GetMethod("get_UtcNow")); il.Emit(OpCodes.Ldstr, ")"); il.EmitCall(OpCodes.Call, miVarargMethod, new Type[] { typeof(DateTime), typeof(string), typeof(DateTime), typeof(string) }); il.Emit(OpCodes.Ret); } static void Main(string[] args) { // How C# code calls vararg method CallVarargMethod(); // Emit IL code to call vararg method with Reflection.Emit string assemblyName = "InMemory"; AssemblyBuilder asmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName(assemblyName), AssemblyBuilderAccess.Run); ModuleBuilder modBldr = asmBldr.DefineDynamicModule(assemblyName); TypeBuilder tb = modBldr.DefineType("C"); MethodBuilder mb = tb.DefineMethod("CallVarargMethod", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, typeof(void), Type.EmptyTypes); EmitCode(mb.GetILGenerator()); Type type = tb.CreateType(); type.GetMethod("CallVarargMethod").Invoke(null, null); // Emit IL code to call vararg method in DynamicMethod DynamicMethod dm = new DynamicMethod("CallVarargMethod", typeof(void), Type.EmptyTypes, typeof(object)); EmitCode(dm.GetILGenerator()); dm.Invoke(null, null); } }