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

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

MSIL实用指南-装箱拆箱的更多相关文章

  1. box unboxing(装箱 拆箱) C#编程指南

    box(装箱)消耗大 box在堆栈中创建一个新的对象,性能消耗大 int i = 123; // Boxing copies the value of i into object o. object ...

  2. Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口

    Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...

  3. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱

    引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...

  4. JAVA的自动装箱拆箱

    转自:http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 蛋呢  的空间 ??什么是自动装箱拆箱 基本数据类型的自动装箱(a ...

  5. NET中的类型和装箱/拆箱原理

    谈到装箱拆箱,DebugLZQ相信给位园子里的博友一定可以娓娓道来,大概的意思就是值类型和引用类型的相互转换呗---值类型到引用类型叫装箱,反之则叫拆箱.这当然没有问题,可是你只知道这么多,那么Deb ...

  6. .net学习之继承、里氏替换原则LSP、虚方法、多态、抽象类、Equals方法、接口、装箱拆箱、字符串

    1.继承(1)创建子类对象的时候,在子类对象中会为子类对象的字段开辟空间,也会为父类的所有字段开辟空间,只不过父类私有的成员访问不到(2)子类从父类继承父类所有的非私有成员,但是父类的所有字段也会创建 ...

  7. Java中的装箱拆箱

    一)  装箱与拆箱 Java中有概念是一切皆对象,因为所有的类都默认继承自Object.但是,对于数据类型是个例外,如short,int,long,float,double, byte,char,bo ...

  8. Java 装箱 拆箱

    Java 自动装箱与拆箱   ??什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供的功能. 一般我们要创建一个类的对象的时候,我 ...

  9. Java 的自动装箱拆箱

    Java 是面向对象的语言,其基本数据类型也就有了相对应的类,称为包装类.以下是基本数据类型对应的包装类: 基本数据类型 包装类 byte(1字节) Byte short(2字节) Short int ...

随机推荐

  1. SCRIPT5007:无法获取属性“show”的值,对象为null或未定义

    1.错误描述 SCRIPT5007:无法获取属性"show"的值,对象为null或未定义            dojo.js,行15.字符11808 2.错误原因    requ ...

  2. 芝麻HTTP:Scrapyd的安装

    Scrapyd是一个用于部署和运行Scrapy项目的工具,有了它,你可以将写好的Scrapy项目上传到云主机并通过API来控制它的运行. 既然是Scrapy项目部署,基本上都使用Linux主机,所以本 ...

  3. css 超出规定行数自动隐藏

     单行overflow: hidden;text-overflow: ellipsis;white-space: nowrap;  多行(兼容各个浏览器)//通过覆盖最后几个字的形式p{positio ...

  4. CF374 Maxim and Array

    贪心 如果有0先变成非0 如果负数的个数 应该变为偶数 之后就是每次将绝对值最小的值加K #include<bits/stdc++.h> using namespace std; cons ...

  5. .Net Core使用Redis的一个入门简单Demo

    本例子讲述一个在.Net core环境中对Redis数据库进行增删改查操作. 首先,要安装好Redis数据库,至于怎么安装,本文不再赘述,可以自行百度,有很详细的教程. 安装好之后,在CMD中输入 r ...

  6. Directory Opus(DO) 个人使用经验 2.0

    设置已有命令的快捷键 设置方法 保存显示格式 保存方法 取消删除确认框 Windows取消删除确认框DO取消删除确认框 设置默认布局 设置方法 备份与恢复 设置已有命令的快捷键 已有命令指的是菜单栏上 ...

  7. js去重

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  8. 【BZOJ1969】航线规划(Link-Cut Tree)

    [BZOJ1969]航线规划(Link-Cut Tree) 题面 BZOJ 题解 删边操作 套路呀 离线读入倒过来做 变成加边操作 现在考虑怎么确定两点直接的关键路径条数 如果是一棵树,那么每条边都是 ...

  9. 反射、Attribute

    1.发射是对类或者对象,查看其类内部的构造. 2.类的组成:属性(PropertyInfo).方法(MethodInfo).字段(FiedInfo).构造函数(ConstructorInfo).事件( ...

  10. HashMap中的resize以及死链的情况

    之前我已经写过关于HashMap的内容了:http://www.cnblogs.com/wang-meng/p/7545725.html 我们都知道HashMap是线程不安全的, 如果多线程来访问会有 ...