淺談C#中的值類型和引用類型
一、基本概念
C#只有兩種數(shù)據(jù)類型:值類型和引用類型
值類型在線程棧分配空間,引用類型在托管堆分配空間
值類型轉(zhuǎn)為引用類型稱成為裝箱,引用類型轉(zhuǎn)為值類型稱為拆箱
以下是值類型和引用類型對照表

從上圖可以簡單看出:string,Object,數(shù)組,class是引用類型,簡單類型,枚舉,結(jié)構(gòu)是值類型。
二、代碼展示
定義一個類和結(jié)構(gòu)調(diào)用賦值

內(nèi)存分配情況如下圖:

從這張圖可以看出,class實例化出來的對象,指向了內(nèi)存堆中分配的空間;truct實例化出來的對象,是在內(nèi)存棧中分配。
修改代碼如下:

內(nèi)存分配情況:

由上圖可以知:
object obj=”abc”;
string i=(string)obj;
值類型和引用類型儲的位置不一樣
如果是引用類型,當(dāng)兩個對象指向同一個地方,修改某一個的時候,其它對象的值會發(fā)生改變
using System;
namespace ConsoleApplication2
{
//引用類型(因為‘class')
public class SomeRef
{
public int x { get; set; }
}
//值類型(因為‘struct')
public struct SomeVal
{
public int x{ get; set; }
}
class Program
{
static void Main(string[] args)
{
SomeRef r1=new SomeRef(); //在堆上分配
SomeVal v1 = new SomeVal();//在棧上分配
r1.x = 5; //提領(lǐng)指針
v1.x = 5; //在棧上修改
Console.WriteLine(r1.x); //顯示5
Console.WriteLine(v1.x); //顯示5
SomeRef r2 =r1; //只復(fù)制引用(指針)
SomeVal v2 =v1; //在棧上分配并賦值成員
r1.x = 8; //r1.x和r2.x都會修改
v1.x = 8; //v1.x會更改,v2.x不會
Console.WriteLine(r1.x); //顯示8
Console.WriteLine(r2.x); //顯示8
Console.WriteLine(v1.x); //顯示8
Console.WriteLine(v2.x); //顯示5
Console.ReadKey();
}
}
}
三、值類型裝箱、拆箱
1、裝箱:就是將值類型的數(shù)據(jù)打包到引用類型的實例中(比如將string類型的值abc賦給object對象obj)
object obj=(object)i;
裝箱時到底發(fā)生的事情:
1)、在托管堆中分配內(nèi)存。分配的內(nèi)存量是值類型各字段所需的內(nèi)存量,還要加上托管堆所有對象都有的兩個額外成員(類型對象指針和同步塊索引)所需的內(nèi)存量
2)、值類型的字段復(fù)制到新分配的堆內(nèi)存
3)、返回對象地址,現(xiàn)在該地址是對象引用;值類型成了引用類型
2、拆箱:就是從引用數(shù)據(jù)中提取值類型(比如將object對象obj的值賦給string類型的變量i)
string i=(string)obj;
拆箱不是裝箱過程倒過來,拆箱的代價愛比裝箱低的多,拆箱是獲取指針的過程,該指針指向包含在一個對象中的原始值類型。
拆箱后將堆中的字段包含的值復(fù)制棧的值類型實例中。
3、值類型變?yōu)橐妙愋筒灰欢ㄒb箱,例如:
string str1 = "joye.net" + 26.ToString(); //tostring后不需要裝箱
感興趣的可以用IL看一下。
相關(guān)文章
C#開發(fā)Windows窗體應(yīng)用程序的簡單操作步驟
這篇文章主要介紹了C#開發(fā)Windows窗體應(yīng)用程序的簡單操作步驟,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04

