装箱的概念
来源:互联网 发布:云计算建设方案 编辑:程序博客网 时间:2024/05/16 11:42
值类型 检查对象实例,确保它是给定值类型的一个装箱值。(拆箱后没有转成原类型,编译时不会出错,但运行会出错,所以一定要确保这一点。用GetType().ToString()判断时一定要使用类型全称,如:System.String 而不要用String。) 将该值从实例复制到值类型变量中。 首先写个简单的控制台程序: 其中object o = i这里我们进行了装箱操作,然后我们用MSIL 反汇编程序查看下生成的.exe程序的内部机理。 其中第12行是我们的装箱操作。(关于IL中出现的操作符代表的操作请查阅MSDN Library中的.NET开发/.NET Framework SDK/类库参考/System.Reflection.Emit/OpCodes 类/OpCodes 字段) 然后我们取消装箱操作: 再用MSIL工具查看生成的.exe,如下结果: 在IL_000a行,我们发现这里却也出现了一个box!不过这步是在call System.Console::WriteLine(string, object)时发生的。我们对比前面我们手动boxing的IL代码,发现在我们手动boxing后就没有这步box了。为什么呢? 当我们在调用一些方法的重载版本时,由于编译器找不到符合给定参数类型的重载方法,此时编译器便去寻找到的最接近的版本,然后使用找到的方法,而其参数却是我们传入的值类型的基类如System.Object或者其实现的接口类型,接着编译器为了求得与这个方法的原型一致,就必须对该值类型进行装箱操作(转换成引用类型)。 照这个说法当我们不手动boxing时,在调用了Console.WriteLine()方法输出一个Int32类型值时,系统就要自动进行 boxing。也就是说如果我们要对该输出操作作5000次的循环,系统就要做5000次的boxing。这样对性能便会有一定的影响,而且要使循环次数是100,000,000次呢,或者跟多! 此时我们便要想如何消除这不应该的性能损失!正如第一个程序是展示的,我们可以在需要的地方先进行boxing,这个原理很简单,我们可以联想到类似的做法: 这样,我们只要一次boxing,就可以避免让系统重复的做这个操作。 像在调用Console.WriteLine()的过程中系统自动进行boxing一样,当我们在调用其它的一些方法的重载版本进行操所时,为了避免由于无谓的隐式装箱所造成的性能损失,在执行这些多类型重载方法之前,最好先对值进行装箱。一般是在处理大量数据需要对类型进行装箱操作。示例
// 装箱与拆箱
using System;
class App
{
static void Main()
{
int i = 32;
object o = i; //隐式装箱
Console.WriteLine("o = {0}", o);
Console.Read();
}
}
2 {
3 .entrypoint
4 // 代码大小 30 (0x1e)
5 .maxstack 2
6 .locals init ([0] int32 i,
7 [1] object o)
8 IL_0000: nop
9 IL_0001: ldc.i4.s 32
10 IL_0003: stloc.0
11 IL_0004: ldloc.0
12 IL_0005: box [mscorlib]System.Int32
13 IL_000a: stloc.1
14 IL_000b: ldstr "o = {0}"
15 IL_0010: ldloc.1
16 IL_0011: call void [mscorlib]System.Console::WriteLine(string,
17 object)
18 IL_0016: nop
19 IL_0017: call int32 [mscorlib]System.Console::Read()
20 IL_001c: pop
21 IL_001d: ret
22 } // end of method App::Main
{
int i = 32;
Console.WriteLine("i = {0}", i);
Console.Read();
}
{
.entrypoint
// 代码大小 28 (0x1c)
.maxstack 2
.locals init ([0] int32 i)
IL_0000: nop
IL_0001: ldc.i4.s 32
IL_0003: stloc.0
IL_0004: ldstr "i = {0}"
IL_0009: ldloc.0
IL_000a: box [mscorlib]System.Int32
IL_000f: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0014: nop
IL_0015: call int32 [mscorlib]System.Console::Read()
IL_001a: pop
IL_001b: ret
} // end of method App::Main
for (int i = 0; i < arr.Length; i++)
{
//
}
//我们更因该这样:
int L = arr.Length;
for (int i = 0; i < L; i++)
{
//
}用途
- 装箱的概念
- 【转】装箱与拆箱的概念及意义
- C# 装箱和拆箱概念的理解
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
- 6个重要的.NET概念: - 堆栈,堆,值类型,引用类型,装箱和拆箱
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
- .NET中六个你必须知道的重要概念之装箱(boxing)和拆箱(unboxing)
- 【面试题研究3】c#中装箱和拆箱的概念
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
- [转]6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
- 6个重要的.NET概念栈,堆,值类型,引用类型,装箱,拆箱
- C# 装箱和拆箱、理论概念
- C# 装箱和拆箱、理论概念
- C# 装箱和拆箱、理论概念
- C# 核心概念--装箱和拆箱
- C#核心概念--装箱和拆箱
- HTML JAVASCRIPT 注册常用检测
- 精简代码实现datagridView 表格打印
- Portal技术综述
- 在VC6.0中编写网络应用程序(Socket)
- Stardock.SoundPackager.v1.2-LiGHTHELL
- 装箱的概念
- 使用PostSharp进行AOP框架设计:从一个简单的原型
- 使用.NET进行WAP开发
- Portal产品介绍--开放源码Portal产品
- gem更新出错时候的解决办法
- 传智播客Java web学习-文件上传组件的应用
- 提高生活幸福感的13个方法
- Eval和Bind
- 看懂乙肝两对半不求人