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

文章来自微软官网: http://msdn.microsoft.com/zh-cn/library/yz2be5wk.aspx


 

  装箱是将值类型转换为object类型或由此值类型实现的任何接口类型的过程。当CLR对值类型进行装箱时,会将该值包装到System.Object内部,再将后者存储在托管堆上。取消装箱将从对象中提取值类型

  装箱是隐式的;取消装箱是显示的。

  装箱和取消装箱的概念是类型系统C#统一视图的基础,其中任一类型的值都被视为一个对象。

在下面的示例中,将整型变量i进行了装箱并分配给对象o。

int i = 123;
object o = i; // 将i装箱

上述语句的结果是在堆栈上创建对象引用o,而在堆上则引用int类型的值。该值是赋给变量i的值类型的一个副本。下图说明了两个变量i和o之间的差异。

BoxingConversion 图

还可以像下面的示例一样执行显式装箱,但显式装箱从来不是必须的:

int i = 123;
object o = (object) i; // 显式装箱

 

然后,可以将对象o取消装箱并分配给整型变量i:

o = 123;
i = (int)o; // 取消装箱

取消装箱操作包括两个步骤:

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);
}    

 

 

转载于:https://www.cnblogs.com/sutingwei/p/3541961.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值