這篇文章主要會簡單探討這三種變數型別如何分類:Primitive Type (基礎型別)、Reference Type(參考型別)、Value Type(資料型別)。但不會提及使用的差異性。若有錯誤,請多多指教。
首先,先簡單介紹一下別名這檔事,以便接下來的說明:
在 C# 的世界中,某些型態有以下左側(C# Built-In Type)與右側(.NET Framework Type)兩種表示法,但其實代表的意義一模一樣,寫哪個都可以。差別只在於左側的是定義在 C# 中;右側的是定義在 .NET Framewrok 中,編譯後都會轉為一樣的東西。所以接下來的介紹,我就不再拘泥使用哪個表示法,明白左右是同樣的意思就好。
object System.Object
string System.String
bool System.Boolean
byte System.Byte
sbyte System.SByte
short System.Int16
ushort System.UInt16
int System.Int32
uint System.UInt32
long System.Int64
ulong System.UInt64
float System.Single
double System.Double
decimal System.Decimal
char System.Char
但雖然左右都是相同的,但在 C# 的規格書-ECMA-334 p.18 中,還是推薦左側這種比較精簡的寫法:
Each of the predefined types is shorthand for a system-provided type. For example, the keyword
int
refers to the structSystem.Int32
. As a matter of style, use of the keyword is favoured over use of the complete system type name.
接下來,就進入正題。先說明一下三種型別的分類關係大概如下:
- Primitive Type (基礎型別)
- Non-Primitive Type (非基礎型別)
--------------------------------------------------- - Value Type (資料型別)
- Reference Type(參考型別)
咦?什麼?你說上面跑出第四種型別嗎?沒錯,為了方便說明,我把 Non-Primitive Type (非基礎型別)直接就列上了。看上面的條列方式,約略可以明白我想表達的意思:資料型別可以用兩種方式來分類,就如同人類可以用男、女來分類,也可以用魔法師、麻瓜(不會魔法的)來分類。
那先來談談 Primitive 與 Non-Primitive 。
Primitive Type
基礎型別的分類,講白了就是直接被定義在 .NET Framework 之中的。使用 Type.IsPrimitive 可以直接查詢是否為 Primitive Type。也就是以下這些型態: Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, Single
。Primitive Type 就這樣,就只是定義而已,講完了。
Non-Primitive Type
沒錯,非 Primitive Type 的就是 Non-Primitive Type 啦~也講完了!
重頭戲來了,談談 Reference Type 與 Value Type。
Value Type
- struct
- enum
- 最上頭提到左邊的 C# Built-In Type 中,除了 object 與 string 之外,其他都是 Value Type,也就是這些:
bool、byte、sbyte、char、decimal、double、float、int、uint、long、ulong、short、ushort
Reference Type
非 Value Type 即 Reference Type,就這樣。也就是以下這些:
- class
- interface
- delegate
- dynamic
- object
- string
結語
- 所以 Primitive Type 與 Value Type、Reference Type 根本就不是同一檔事,不要再問「xxx 是屬於 Primitive Type 還是 Reference Type?」了,這問題本身就怪怪的,就像是問說「妙麗是女生還是魔法師?」一樣奇妙。
- 從上頭的整理可以看到,C# 的世界中,Primitive Type 一定是 Value Type,但 Value Type 不見得是 Primitive Type(DateTime 就是個反例)。
- 變數型態的大小寫與 Value Type 、Reference Type 毫無關係。例如:int、string、System.Int32、String、...。