zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    PMP(第六版)十大知识领域、五大项目管理过程组、49个过程矩阵
    快速开发平台分享-UCML快速开发七种武器
    敏捷开发干货-快速开发平台的主题行为模型介绍
    MACHINE LEARNING
    What is “Neural Network”
    VS打开项目或解决方案卡死,一直处于未响应状态。
    Sql Server 本地(客户端)连接服务器端操作
    阿里云服务器,Sql Server 本地连接服务器端问题记录
    <%@ Register TagPrefix="uc1" TagName="user" Src="../Control/user.ascx" %>什么意思?
    IIS网站部署后,程序常见错误记录
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8664536.html
Copyright © 2011-2022 走看看