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 = ;
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实用指南-装箱拆箱的更多相关文章
- box unboxing(装箱 拆箱) C#编程指南
box(装箱)消耗大 box在堆栈中创建一个新的对象,性能消耗大 int i = 123; // Boxing copies the value of i into object o. object ...
- Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口
Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...
- JAVA的自动装箱拆箱
转自:http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 蛋呢 的空间 ??什么是自动装箱拆箱 基本数据类型的自动装箱(a ...
- NET中的类型和装箱/拆箱原理
谈到装箱拆箱,DebugLZQ相信给位园子里的博友一定可以娓娓道来,大概的意思就是值类型和引用类型的相互转换呗---值类型到引用类型叫装箱,反之则叫拆箱.这当然没有问题,可是你只知道这么多,那么Deb ...
- .net学习之继承、里氏替换原则LSP、虚方法、多态、抽象类、Equals方法、接口、装箱拆箱、字符串
1.继承(1)创建子类对象的时候,在子类对象中会为子类对象的字段开辟空间,也会为父类的所有字段开辟空间,只不过父类私有的成员访问不到(2)子类从父类继承父类所有的非私有成员,但是父类的所有字段也会创建 ...
- Java中的装箱拆箱
一) 装箱与拆箱 Java中有概念是一切皆对象,因为所有的类都默认继承自Object.但是,对于数据类型是个例外,如short,int,long,float,double, byte,char,bo ...
- Java 装箱 拆箱
Java 自动装箱与拆箱 ??什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供的功能. 一般我们要创建一个类的对象的时候,我 ...
- Java 的自动装箱拆箱
Java 是面向对象的语言,其基本数据类型也就有了相对应的类,称为包装类.以下是基本数据类型对应的包装类: 基本数据类型 包装类 byte(1字节) Byte short(2字节) Short int ...
随机推荐
- JSP常见的三个编译指令
JSP常见的三个编译指令 1.page指令 是针对当前页面的指令 2.include指令 用于指定包含另一个页面 3.taglib指令 用于定义和访问自定义标签
- Codeforces Round #427 (Div. 2) D - Palindromic characteristics
本题是个简单的区间dp 最近都没时间做题了,被我妈强制喊回去,然后颓废了10天(回家也没发控制住自己= = 我的锅),计划都打乱了,本来还报名了百度之星,然后没时间参加 #include<cma ...
- Qt5.6.0+OpenGL 纹理贴图首战告捷
重要的话写在前面~~通过今晚的实验,知道了EBO是不能随便release的~~~一直不要release就可以了,否则vao会失效 Display.h #ifndef DISPLAYWIDGET_H # ...
- 微信小程序hidden
首先hidden默认在display:block;情况下是会默认生效的: but在很多时候只在初始值下有效, 在data下声明 flag:true; 方法中: 无效,所以尽量不要使用hidden这个属 ...
- Web前端开发学习笔记(二)
Homework2:http://my.ss.sysu.edu.cn/wiki/display/WEB/Homework+2+-+Movie+Review 这份作业跟布局相关,因此很多都是布局的知识: ...
- 三大家族,offset,scroll,client
1.client 1.1主要成员 1.clientWidth 获取网页可视区域宽度(两种用法) clientHeight 获取网页可视区域高度 (两张用法) 盒子调用: 指盒子本省 浏览器调用: ...
- 找出k个数相加得n的所有组合
Find all possible combinations of k positive numbers that add up to a number n,each combination shou ...
- Linux 下 vim 编辑文件,解决中文乱码,设置Tab键空格数
vim编辑文件的时候,输入中文就出现乱码 解决办法: 以哪个用户登录的就在哪个用户目录下创建文件 vimrc vim .vimrc (.创建的是隐藏文件) 文件内容: set tabsto ...
- js备战春招の三
DOM (Document Object Model)(文档对象模型)是用于访问 HTML 元素的正式 W3C 标准. window.alert() 弹出警告框. document.write() 方 ...
- JavaScript中的execCommand
execCommand方法是执行一个对当前文档,当前选择或者给出范围的命令.处理Html数据时常用 如下格式:document.execCommand(sCommand[,交互方式, 动态参数]) , ...