MSIL实用指南-装箱拆箱
本篇讲述怎样装箱拆箱。装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大。
装箱
装箱指令是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 { /// <summary> /// 装箱拆箱 /// </summary> 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); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?