淺談C#中的值類型和援用類型。本站提示廣大學習愛好者:(淺談C#中的值類型和援用類型)文章只能為提供參考,不一定能成為您想要的結果。以下是淺談C#中的值類型和援用類型正文
1、根本概念
C#只要兩種數據類型:值類型和援用類型
值類型在線程棧分派空間,援用類型在托管堆分派空間
值類型轉為援用類型稱成為裝箱,援用類型轉為值類型稱為拆箱
以下是值類型和援用類型對比表
從上圖可以簡略看出:string,Object,數組,class是援用類型,簡略類型,列舉,構造是值類型。
2、代碼展現
界說一個類和構造挪用賦值
內存分派情形以下圖:
從這張圖可以看出,class實例化出來的對象,指向了內存堆平分配的空間;truct實例化出來的對象,是在內存棧平分配。
修正代碼以下:
內存分派情形:
由上圖可以知:
object obj=”abc”;
string i=(string)obj;
值類型和援用類型儲的地位紛歧樣
假如是援用類型,當兩個對象指向統一個處所,修正某一個的時刻,其它對象的值會產生轉變
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; //提領指針 v1.x = 5; //在棧上修正 Console.WriteLine(r1.x); //顯示5 Console.WriteLine(v1.x); //顯示5 SomeRef r2 =r1; //只復制援用(指針) 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(); } } }
3、值類型裝箱、拆箱
1、裝箱:就是將值類型的數據打包到援用類型的實例中(好比將string類型的值abc賦給object對象obj)
String i=”abc”;
object obj=(object)i;
裝箱時究竟產生的工作:
1)、在托管堆平分配內存。分派的內存量是值類型各字段所需的內存量,還要加上托管堆一切對象都有的兩個額定成員(類型對象指針和同步塊索引)所需的內存量
2)、值類型的字段復制到新分派的堆內存
3)、前往對象地址,如今該地址是對象援用;值類型成了援用類型
2、拆箱:就是從援用數據中提取值類型(好比將object對象obj的值賦給string類型的變量i)
object obj=”abc”;
string i=(string)obj;
拆箱不是裝箱進程倒過去,拆箱的價值愛比裝箱低的多,拆箱是獲得指針的進程,該指針指向包括在一個對象中的原始值類型。
拆箱後將堆中的字段包括的值復制棧的值類型實例中。
3、值類型變成援用類型紛歧定要裝箱,例如:
string str = "joye.net" + 26; //須要將26裝箱為string類型
string str1 = "joye.net" + 26.ToString(); //tostring後不須要裝箱
感興致的可以用IL看一下。