装箱
装箱指令是Box。使用格式是 ILGenerator.Emit(OpCodes.Box,<值类型>); 装箱当然是对一个值类型装箱的,所以第二个参数一定是int,float等一类的值类型。实例:ilGenerator.Emit(OpCodes.Box,typeof(int));
拆箱
拆箱指令是OpCodes.Unbox_Any和OpCodes.Unbox。他们的区别是Unbox指令不包含伴随着拆箱的字段复制操作,但是Unbox_Any则包含伴随着拆箱的字段复制操作。OpCodes.Unbox一般不用,所以这里不讲解它。
OpCodes.Unbox_Any的格式是 ILGenerator.Emit(OpCodes.Unbox_Any,<值类型>);拆箱也是对一个值类型装箱的,所以第二个参数也是值类型。 拆箱也是对一个值类型装箱的,所以第二个参数也是值类型。实例:ilGenerator.Emit(OpCodes.Unbox_Any, typeof(double));
生成C#程序为
object obj = 2147483647; Console.WriteLine(obj); int value = (int)obj; Console.WriteLine(value); object obj2 = 1.7976931348623157E+308; Console.WriteLine(obj2); double value2 = (double)obj2; Console.WriteLine(value2);
完整程序如下:
using System;using System.Reflection;using System.Reflection.Emit;namespace LX1_ILDemo{ ////// 装箱拆箱 /// class Demo14_BoxUnBox { static string binaryName = "Demo14_BoxUnBox.exe"; static string namespaceName = "LX1_ILDemo"; static string typeName = "BoxUnBox"; static AssemblyBuilder assemblyBuilder; static ModuleBuilder moduleBuilder; static TypeBuilder typeBuilder; static MethodBuilder mainMethod; static ILGenerator ilGenerator; static void Emit_Codes() { LocalBuilder loca1 = ilGenerator.DeclareLocal(typeof(object)); LocalBuilder loca2 = ilGenerator.DeclareLocal(typeof(int)); LocalBuilder loca3 = ilGenerator.DeclareLocal(typeof(object)); LocalBuilder loca4 = ilGenerator.DeclareLocal(typeof(double)); ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue); ilGenerator.Emit(OpCodes.Box,typeof(int)); ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) })); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Unbox_Any, typeof(int)); ilGenerator.Emit(OpCodes.Stloc_1); ilGenerator.Emit(OpCodes.Ldloc_1); ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) })); ilGenerator.Emit(OpCodes.Ldc_R8, double.MaxValue); ilGenerator.Emit(OpCodes.Box, typeof(double)); ilGenerator.Emit(OpCodes.Stloc_2); ilGenerator.Emit(OpCodes.Ldloc_2); ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) })); ilGenerator.Emit(OpCodes.Ldloc_2); ilGenerator.Emit(OpCodes.Unbox_Any, typeof(double)); ilGenerator.Emit(OpCodes.Stloc_3); ilGenerator.Emit(OpCodes.Ldloc_3); ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(double) })); } public static void Generate() { InitAssembly(); typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public); /* 生成 public static void Main() */ GenerateMain(); Emit_Codes(); EmitReadKey(); ilGenerator.Emit(OpCodes.Ret); /* 设置assembly入口方法 */ assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication); SaveAssembly(); Console.WriteLine("生成成功"); } static void EmitReadKey() { /* 生成 Console.ReadKey(); */ MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { }); ilGenerator.Emit(OpCodes.Call, readKeyMethod); ilGenerator.Emit(OpCodes.Pop); } static void GenerateMain() { mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { }); ilGenerator = mainMethod.GetILGenerator(); } static void InitAssembly() { AssemblyName assemblyName = new AssemblyName(namespaceName); assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName); } static void SaveAssembly() { Type t = typeBuilder.CreateType(); //完成Type,这是必须的 assemblyBuilder.Save(binaryName); } }}