程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 淺談C#中所謂的“值類型”

淺談C#中所謂的“值類型”

編輯:關於C語言

在C#中,相信大家對於 "值類型" 並不陌生,因為它在我們代碼設計中是不可缺少的,那麼究竟什麼是 "值類型" 呢? "值類型"就是 我們用到的 Int16,Int32這些數值類型嗎?

我們知道在C#中所有的類型繼承於System.Object根類型,這也就意味著就代碼層面來講,在C#中所有的類型都是Class,,即一切都是Class類型,既然全部都是Class類型,那麼值類型在哪裡呢?我們可以發現在C#中System.Int16,System.Int32,System.Boolean...等等這些常用的類型都是Struct 結構類型,那麼結構類型是什麼,下面我們定義一個結構,然後通過IL Disassemble 工具來查看編譯的中間代碼便可以得到結果.

public struct CustomerStruct

{

public string Name{get;set;}

}

代碼非常簡單,我們就定義一個struct類型,並且包含一個Name屬性.

看到上面這幅圖,相信大家都已經看到定義一個struct類型實際上編譯把你所定義的類型繼承了System.ValueType類型,換句話說,在C#中我們經常使用的System.Int16,System.Int32,System.Boolean..這些數值結構類型都是繼承於System.ValueType類型,而System.ValueType又是繼承於System.Object根類型,即驗證我開始所講到的在C#中一切類型都是Class。

之所以存在"值類型" 這個概念,其實是因為C#中的某些類型有這特殊的地位(即繼承於System.ValueType的類型),CLR會特殊的對待這些類型,

看下面這2行代碼 

Int32 a = new System.Int32(10) ;

CustomerStruct customer = new CustomerStruct() ;

首先為什麼對於數值類型也可以使用 new 來進行內存分配呢? 上面已經講到,因為他們都是Class類型,當然可以使用new 來進行內存分配.

其次,CLR執行這樣的代碼的時,CLR 通過反射(有待考察)或者其他途徑來獲知所要請求分配內存的類型是否繼承於System.ValueType如果是的話,那麼就在棧上進行分配,如果不是的話,那麼就是我們所說的引用類型,就在托管堆上分配內存以及棧上分配對應的引用變量,這些一切都是CLR做的工作.

我們再來看看裝箱操作.

object o = new object();

Int32 aaa = 100;

o = aaa; //這裡會發生裝箱操作

我們都知道當CLR執行到 o = aaa;這條語句時會發生裝箱操作,為什麼會發生裝箱操作呢?這是因為CLR 知道引用變量o所要引用的類型aaa是繼承於System.ValueType類型的,繼承於System.ValueType的類型都是在棧上分配的,而其它則是在托管堆上分配的,所以會CLR會弄得aaa的副本弄到托管堆上去,這一切也都是CLR的工作.

由此我們可以得出結論:

1.在C#中 就代碼層面上講 所有的類型都是Class類型.

2.所謂的 "值類型" != 數值類型,而是所有繼承於System.ValueType 的類型.

3."值類型" 得到的語言級別的支持,CLR知道如何對 "值類型" 這樣的Class類型進行內存分配和處理.

綜上所述.個人愚見,有什麼不對的地方希望大家幫忙指出,共同學習,共同進步.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved