关于值类型和引用类型已经有很多人写了很多文章,但是很多人也只是停留在字面上的理解,如果采用一种通俗的方法来解释,想必很多人都会理解。我们都知道值类型存储在栈上,引用类型存储在堆上,引用类型都是xxx类,值类型都是xxx结构(structure)。下面先放一张图
// 引用类型 因为有class class SomeRef { public Int32 x; } // 值类型 因为是struct struct SomeVal { public Int32 x; } static void ValueTypeDemo() { SomeRef r1 = new SomeRef(); // 分配在堆上 SomeVal v1 = new SomeVal(); // 分配在栈上 r1.x = 5; v1.x = 5; Console.WriteLine(r1.x); // 结果为"5" Console.WriteLine(v1.x); // 同样也是 "5" SomeRef r2 = r1; SomeVal v2 = v1; r1.x = 8; v1.x = 9; Console.WriteLine(r1.x); // 结果为"8" Console.WriteLine(r2.x); // 结果为"8" Console.WriteLine(v1.x); // 结果为"9" Console.WriteLine(v2.x); // 结果为"5" }
从代码和图可以看的很清楚,下面我们结合装箱和拆箱谈一谈值类型和引用类型。
通俗一点的理解
一个应用程序的启动可以理解为你开了一个商店,商店的店铺相当于栈,商店的仓库相当于堆,对于有些小的商品,比如打火机之类的,仓库就没必要存货了,而对于手提箱之类的大件,商店里面只是放一个作为展示,当你去商店里面买东西的时候,直接从商店里那,效率是最快的,你在商店里选好了东西去仓库里取,效率就会低一些。想必到这里你就会明白堆和栈了。商店倒闭的时候,商店里面的东西要全部进行处理,而仓库里面的东西需要等待一段时间(GC)。
接下来说一下装箱和拆箱,由于一些特殊的需要,我们需要把值类型转换成引用类型(装箱),引用类型在转换成值类型(拆箱),比如超市里面存包裹,你的包裹由于不能带到超市里面,但是你又不能把你包裹扔掉,所以这时候可以给你提供一个箱子,你把你的包裹存到箱子里面(装箱),然后给你一张存包的卡片,等你购物完成后,就需要凭卡片取出包裹(拆箱)。当然这只是比较通俗的理解,可能跟实际的定义有出入,也希望大家多多提出意见和观点,把技术通俗话有助于我们的理解。