文章来自微软官网: http://msdn.microsoft.com/zh-cn/library/yz2be5wk.aspx函数
装箱是将值类型转换为object类型或由此值类型实现的任何接口类型的过程。当CLR对值类型进行装箱时,会将该值包装到System.Object内部,再将后者存储在托管堆上。取消装箱将从对象中提取值类型。性能
装箱是隐式的;取消装箱是显示的。优化
装箱和取消装箱的概念是类型系统C#统一视图的基础,其中任一类型的值都被视为一个对象。spa
在下面的示例中,将整型变量i进行了装箱并分配给对象o。code
int i = 123; object o = i; // 将i装箱
上述语句的结果是在堆栈上建立对象引用o,而在堆上则引用int类型的值。该值是赋给变量i的值类型的一个副本。下图说明了两个变量i和o之间的差别。对象
还能够像下面的示例同样执行显式装箱,但显式装箱历来不是必须的:blog
int i = 123; object o = (object) i; // 显式装箱
而后,能够将对象o取消装箱并分配给整型变量i:接口
o = 123; i = (int)o; // 取消装箱
取消装箱操做包括两个步骤:get
1. 检查对象实例,以确保它是给定值类型的装箱值。编译器
2. 将该值从实例复制到值类型变量中。
下面的语句演示装箱和取消装箱两种操做:
int i = 123; // 值类型 object o = i; // 装箱 int j = (int)o; // 取消装箱
下图演示上述语句的结果。
取消装箱转换
要在运行时成功取消装箱值类型,被取消装箱的项必须是对一个对象的引用,该对象是先前经过装箱该值类型的实例建立的。尝试取消装箱null会致使NullReferenceException。尝试取消装箱对不兼容值类型的引用会致使InvalidCastException。
如下示例演示如何在C#中使用装箱。
// String.Concat 示例. // String.Concat 函数有不少版本,下面这个版本的函数的3个参数 // 都必须为Object对象类型,因此 42 和 true 都将被装箱。 Console.WriteLine(String.Concat("Answer", 42, true));
装箱性能相关(以Unity中Debug.Log(object)函数为例)
考虑一种基本的装箱状况,当使用Debug.Log(object)函数时,函数的参数类型为object,也就意味着任何类型的变量都能传递给这个函数。例如当咱们传递一个整数的时候,编译器将会对传递进来的整数进行装箱操做使其变成object类型,而咱们知道装箱操做是须要耗费一点时间的,那么咱们能够经过预见装箱操做来对其作必定的优化工做。以下面这个极端的例子所示:
// 编译器不须要每次调用Debug.Log函数的时候都执行装箱操做 void PrintingManyTimes(int n) { object obj = n; for (int i = 0; i < 500; i++) Debug.Log(obj); }