博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MSIL实用指南-装箱拆箱
阅读量:5247 次
发布时间:2019-06-14

本文共 4570 字,大约阅读时间需要 15 分钟。

本篇讲述怎样装箱拆箱。装箱和拆箱都是针对值类型而言的,装箱的性能开销远比拆箱的性能开销大。

装箱

装箱指令是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);        }    }}
View Code

 

转载于:https://www.cnblogs.com/tkt2016/p/8664536.html

你可能感兴趣的文章
go 学习笔记(4) ---项目结构
查看>>
java中静态代码块的用法 static用法详解
查看>>
Java线程面试题
查看>>
Paper Reading: Relation Networks for Object Detection
查看>>
day22 01 初识面向对象----简单的人狗大战小游戏
查看>>
mybatis源代码分析:深入了解mybatis延迟加载机制
查看>>
Flask三剑客
查看>>
Hibernate-缓存
查看>>
【BZOJ4516】生成魔咒(后缀自动机)
查看>>
提高PHP性能的10条建议
查看>>
svn“Previous operation has not finished; run 'cleanup' if it was interrupted“报错的解决方法...
查看>>
熟用TableView
查看>>
Java大数——a^b + b^a
查看>>
poj 3164 最小树形图(朱刘算法)
查看>>
服务器内存泄露 , 重启后恢复问题解决方案
查看>>
android一些细节问题
查看>>
KDESVN中commit时出现containing working copy admin area is missing错误提示
查看>>
利用AOP写2PC框架(二)
查看>>
【动态规划】skiing
查看>>
java定时器的使用(Timer)
查看>>