你真的了解装箱(Boxing)和拆箱(Unboxing)吗?
所谓装箱就是装箱是将值类型转换为 object 类型或由此值类型实现的任一接口类型的过程。而拆箱就是反过来了。很多人可能都知道这一点,但是是否真的就很了解boxing和unboxing了呢?可以看下下面一段代码,里面发生了几次装箱过程?
public static void Main(string[] args)
{
Int32 v = ;
Object o = v;
v = ;
Console.WriteLine(v+" , "+(Int32)o);
}
不少人可能认为只有一次装箱,其实里面发生了3次装箱过程,是不是很意外!
第一次很明显,就在 Object o = v;时发生。
第二次和第三次都是发生在Writeline()方法里面了。调用此方法是要求获取一个String对象,但是,当前没有字符串对象,它只有三个数据项可以用:一个未装箱的Int32值类型的实例(v),一个String(是一个引用类型),以及一个已经装箱的Int32值类型实例的引用(o),它需要转化成一个未装箱Int32的值类型。所以必须以某种方式对这些数据进行合并,以创建一个String。
为了创建String,C#编译器会生成代码来调用String对象的静态方法Concat。这个方法有好几个重载版本,由于需要把三个数据项连接起来,所以编译器选择的是:
public static string Concat(
Object arg0,
Object arg1,
Object arg2
)
为第一个参数arg0传入的是值类型v,但arg0是一个Object,所以必须对v进行装箱,并将已经装箱的v的地址传给arg0。为arg1参数传递的是一个" , ",它本质上是一个String对象的引用,无需装箱。最后对于arg2,o(一个Object对象的引用)会转换成一个Int32,这要求执行一次拆箱操作(但不紧接着执行一次复制操作),从而获取在已装箱Int32中未装箱的Int32的地址。这个未装箱的Int32实例必须再次装箱,并将新的已装箱实例的地址传给Concat的arg2参数。
然后Concat调用指定的每个对象的TosSring方法,并连接每个对象的字符串表示,最终由WriteLine方法显示出来。
最新文章
- 线性数据结构之栈——Stack
- solr-web界面增加登录认证
- JavaScript学习笔记-JSON对象
- 目标检测的图像特征提取之(一)HOG特征(转载)
- POJ3415 Common Substrings
- CentOS6.5下 yum安装LAMP
- MySql Error: Can't update table in stored function/trigger
- css的框架——common.css
- 开启CURL扩展,让服务器支持PHP curl函数(远程采集)
- careercup-排序和查找 11.1
- jquery插件--多行文本缩略
- Effective MySQL之备份与恢复
- PHP - 数学运算
- Android中吐司当前电池电量
- VS2013使用EF与mysql数据库.
- (转)如何阅读OpenStack源码
- [原创]K8Cscan插件之Mysql密码爆破
- 这样使用 GPU 渲染 CSS 动画(转)
- Blink
- [USACO08NOV]Time Management
热门文章
- 【CString与string转换】不存在从 ";LPWSTR"; 转换到 ";std::basic_string<;char, std::char_traits<;char>;, std::allocator(转)
- BeeFramework 笔记 四(UISignal 总结)
- VS2013 MFC C++ CString ,const char , char, string 类型转换
- 和菜鸟一起学linux之V4L2摄像头应用流程【转】
- python bisect模块二分法查找
- kubernetes 搭建集群外部ip服务
- QueryDict对象
- js-offsetX、pageX、clientX、layerX、screenX
- 818E - Card Game Again(尺取法)
- 浅谈如何做好Bug回归验证?