惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 怀雷

关于C指针 堆、栈和本地堆浅析 TCP/IP简介 IP协议简介 RARP―――逆地址解析协议 在传统以太网中,为什么要有最小帧长度和最大帧长度的限制? 计算机网络原理与Internet技术(第五章) 计算机网络原理与Iternet技术(第四章) 计算机网络原理与Iternet技术(第三章) 计算机网络原理与Iternet技术(第二章) 计算机网络原理与Internet技术(第一章) ARP协议简介 Effective C# 原则2:为你的常量选择readonly而不是const[转载] 在数据库中创建定时任务[原创] 往事以矣 说事[转帖] 分部类(Partial Classes)[原创] 大连出差最大的收获 Page_Load()中IsPostBack用法浅析[原创]
装箱(Boxing)和拆箱(Unboxing)[原创]
怀雷 · 2006-12-31 · via 博客园 - 怀雷

装箱(Boxing)和拆箱(Unboxing
                              --自己总结的,有说的不好的地方,请指出

一、在说装箱和拆箱之前得先说一下变量的类型。

C#支持两种变量类型:值类型和引用类型。其中:值类型是指那些基本数据类型。如intdoublechar和用struct声明的用户定义类型等;而引用类型指从基本类型构造而来的类和其它复杂数据类型。

值类型变量保存的是类型的实例,而引用类型的变量保存的不是类型的实例,保存的是实例的引用。

举个例子:创建两个值类型变量ij

int i=7;

int j=i;

则它们在内存中是独立保存的,值类型的变量之间没有任何联系。如果我们改变某一个值,另一个值不会有任何影响。

下面看一下引用类型的变量的情况:

我们声明并实例化下面两个变量:

myClass Class_A=new myClass();

myClass Class_B=Class_A;

它们在内存中的保存方式如下: 

假设在位置0X80000保存类的实例,Class_A保存的是对类实例的引用,即保存的是地址0X80000,Class_B是对Class_A的独立引用,但保存的也是对类实例的引用。

因为类在C#中是引用类型,所以Class_A称为对myClass的引用。第一行代码先在内存中创建myClass的一个实例,并且将Class_A设置为引用该实例。因此,当将Class_A的值赋给Class_B时,Class_B保存的也是该类的实例的引用。如果我们改变Class_A中的属性,则Class_B中也会反映这些改变。

清楚了值类型和引用类型,下面就该说说装箱和拆箱了。

二、装箱和拆箱

将值类型转换为引用类型的过程称为装箱;将引用类型转换为值类型的过程称为拆箱。

2.1 装箱:

如下代码所示:

int i=123;

//object所有其他类型的基本类型,代表的类是System.Object

object o=(object) i;     //装箱

装箱的过程是:将i=123复制一份放入堆中,在栈中创建一个object oo保存的是堆中存放i=123的地址。如下图所示:

2.1 装箱的变化过程

下面看个例子:

Using System;

Class TestBoxing

{

    Public static void Main()

    {

        int i=123;

        object 0=i;

        i=456;

        Console.WriteLine(“The value-Type value = {0}”,i);

        Console.WriteLine(“The object-Type value = {0}”,o);

    }

}

Output:

The value-Type value =456

The object-Type value =123

2.2 拆箱

拆箱的过程基本类似.

如下代码所示:

int i=123;

object o=(object) i;     //装箱

int j=(int) o;          //拆箱

过程如下图所示:

2.2 拆箱的变化过程

拆箱的时候要注意:隐式转换的类型要跟装箱前的类型相同,否则会有异常产生。

三、总结

C# 将所有的基本数据类型都表示为对象(object),所以按照基本数据类型(object)来调用对象方法是可行的。借助于自动装箱拆箱,可以达到此目的。所以理解装箱和拆箱就很有必要了。但是按照基本数据类型来调用对象方法有一些问题或者说缺点,例如:会造成很多垃圾内存,还会使程序的效率下降等。

C2.0中引入了新的语法规则――泛型(我认为是C#升级中最大的改进^_^),它很好地解决了这些问题。过些日子我会总结一下我对泛型的一些认识,希望能对看到我的博客的朋友们有些帮助。