【C# 装箱(Boxing)与取消装箱(Unboxing)】

文章来自微软官网: 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之间的差别。对象

BoxingConversion 图

还能够像下面的示例同样执行显式装箱,但显式装箱历来不是必须的: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);
}    
相关文章
相关标签/搜索