• 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);
            }
        }
    }
    View Code
  • 相关阅读:
    String分割成int[]和List<Integer>
    linux查询正在运行的jar包并kill进程
    linux自动清理n天(1个月)前日志文件
    zookeeper命令行操作
    sql开窗函数
    hdfs shell操作
    centos7安装mysql8
    hadoop集群安装
    hdfs基本介绍
    IDEA下运行MAVEN项目,报"程序包******不存在"
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8664536.html
Copyright © 2020-2023  润新知