国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

淺談C#中的值類型和引用類型

2019-10-29 21:26:00
字體:
來源:轉載
供稿:網友

一、基本概念

C#只有兩種數據類型:值類型和引用類型

值類型在線程棧分配空間,引用類型在托管堆分配空間

值類型轉為引用類型稱成為裝箱,引用類型轉為值類型稱為拆箱

以下是值類型和引用類型對照表

c#引用類型,c#值類型和引用類型,c#,string是引用類型

從上圖可以簡單看出:string,Object,數組,class是引用類型,簡單類型,枚舉,結構是值類型。

二、代碼展示

定義一個類和結構調用賦值

c#引用類型,c#值類型和引用類型,c#,string是引用類型

內存分配情況如下圖:

c#引用類型,c#值類型和引用類型,c#,string是引用類型

從這張圖可以看出,class實例化出來的對象,指向了內存堆中分配的空間;truct實例化出來的對象,是在內存棧中分配。

修改代碼如下:

c#引用類型,c#值類型和引用類型,c#,string是引用類型

內存分配情況:

c#引用類型,c#值類型和引用類型,c#,string是引用類型

由上圖可以知:

 

復制代碼 代碼如下:

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();    }  }}

三、值類型裝箱、拆箱

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看一下。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鄢陵县| 天门市| 商南县| 宕昌县| 鄂尔多斯市| 宝鸡市| 绍兴市| 长治县| 精河县| 昭通市| 苍梧县| 龙口市| 攀枝花市| 武义县| 厦门市| 红桥区| 威海市| 龙江县| 通渭县| 江川县| 临洮县| 秀山| 水富县| 井研县| 晋江市| 建瓯市| 宁陵县| 嘉义县| 诏安县| 金门县| 灵丘县| 新和县| 五家渠市| 昌乐县| 东山县| 韩城市| 五华县| 牡丹江市| 社旗县| 大城县| 韩城市|