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 ...
随机推荐
- R语言︱SNA-社会关系网络 R语言实现专题(基础篇)(一)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 笔者寄语:这里所有的应用代码都来自与igrap ...
- php出现Can't use function return value in write context
<?php if(session('uid')){ }else{ } ?> 在用empty判断值为空的时候,报了这个Can't use function return value in w ...
- 《实战Nginx》读书笔记--Nginx配置文件
先看下一份的Nginx 的配置 #user nobody nobody;#使用的用户和组 worker_processes 4;#工作进程的个数,一般等于CPU核数或者总核数的两倍 #error_lo ...
- VxWorks6.6 pcPentium BSP 使用说明(三):设备驱动
本文主要介绍了pcPentium BSP中包含的驱动程序.包含了官方提供的所有驱动程序,除了aic7888Lib--现在已用得很少的一个AIC-7888 SCSI控制器的驱动介绍.建议重点阅读at ...
- Linux显示inode的信息
Linux显示inode的信息 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ df -i 文件系统 Inode 已用(I) 可用(I) 已用(I)% 挂载点 ...
- RHCE6.4 rpm 安装gcc
先将gcc的iso里的Packages拷贝到根目录下,方便以后使用,再找gcc的rpm包安装: 网上说有以下依赖,需要按照一下顺序安装: rpm -ivh cpp*****.rpm rpm -ivh ...
- Linux系统 awk sed R脚本 python脚本传入变量
sed 传入变量: chrI="chr2";sed -n "/$chrI/p" clippointpos.csv #变量用$var表示,把sed的单引号变为双 ...
- AJAX跨域问题总结
跨域是什么? 首先说下同源,同源策略是浏览器的一种安全策略,所谓同源是指,域名,协议,端口完全相同.而跨域就是不同源 ! 能够进行跨域的请求 一般a,img,link[rel=stylesheet], ...
- 【转】MySQL乐观锁在分布式场景下的实践
背景 在电商购物的场景下,当我们点击购物时,后端服务就会对相应的商品进行减库存操作.在单实例部署的情况,我们可以简单地使用JVM提供的锁机制对减库存操作进行加锁,防止多个用户同时点击购买后导致的库存不 ...
- 深度学习——卷积神经网络 的经典网络(LeNet-5、AlexNet、ZFNet、VGG-16、GoogLeNet、ResNet)
一.CNN卷积神经网络的经典网络综述 下面图片参照博客:http://blog.csdn.net/cyh_24/article/details/51440344 二.LeNet-5网络 输入尺寸:32 ...