C# 是強型別語言,每個變數、常數、運算式皆有明確型別。理解值/參考型別差異、Boxing/Unboxing 機制,是寫出高效、正確程式的關鍵。
值型別變數直接儲存資料本身,指派時會複製值。分類如下:
對應 .NET 系統型別別名,支援常數運算式編譯期求值,可用常值初始化。
| 分類 | C# 關鍵字 | .NET 型別 | 範圍/精度 |
|---|---|---|---|
| 整數 | sbyte | System.SByte | 有號 8-bit:-128 ~ 127 |
byte | System.Byte | 無號 8-bit:0 ~ 255 | |
short | System.Int16 | 有號 16-bit:-32,768 ~ 32,767 | |
ushort | System.UInt16 | 無號 16-bit:0 ~ 65,535 | |
int | System.Int32 | 有號 32-bit:-2,147,483,648 ~ 2,147,483,647 | |
uint | System.UInt32 | 無號 32-bit:0 ~ 4,294,967,295 | |
long | System.Int64 | 有號 64-bit:±9.22×10¹⁸ | |
ulong | System.UInt64 | 無號 64-bit:0 ~ 1.84×10¹⁹ | |
char | System.Char | UTF-16 字元(16-bit) | |
| 布林 | bool | System.Boolean | true/false,不可隱式轉換整數 |
| 浮點 | float | System.Single | ±1.5×10⁻⁴⁵ ~ ±3.4×10³⁸,7 位精度 |
double | System.Double | ±5.0×10⁻³²⁴ ~ ±1.7×10³⁰⁸,15-16 位精度 | |
| 十進位 | decimal | System.Decimal | 128-bit,28-29 位有效數字,適合金融計算 |
int/long 大小固定,不隨平台變化(不同於 C/C++)bool 僅接受 true/false,if (x = 1) 會編譯錯誤char 為 UTF-16,無隱式轉換至數值型別,需強制轉型decimal 無隱式轉換至/自 double,避免精度遺失/溢位關鍵字 struct 定義,值型別語意但擁有類別特性:可含建構函式、方法、屬性、索引子、運算子、巢狀型別。主要用途:小型、不可變、高頻率建立的物件(如 Point、DateTime)。
struct IPAddress
{
public byte Octet1, Octet2, Octet3, Octet4;
public override string ToString() => $"{Octet1}.{Octet2}.{Octet3}.{Octet4}";
}
// 使用
IPAddress ip;
ip.Octet1 = 192; ip.Octet2 = 168; ip.Octet3 = 1; ip.Octet4 = 1;
Console.WriteLine(ip); // 192.168.1.1
優勢:陣列儲存千萬個結構時,無額外參考負擔,記憶體連續、Cache 友善。
定義具名常數集合,底層為整數型別(預設 int)。
enum Month : byte { Jan = 1, Feb, Mar, Apr } // 指定底層型別與起始值
enum Flags { None = 0, Read = 1, Write = 2, Execute = 4 } // 位旗標
參考型別變數儲存物件參考,指派時複製參考,多個變數可指向同一物件。
| 型別 | 說明 |
|---|---|
object | 所有型別的終極基類,任何值可指派給它(觸發 Boxing) |
class | 自訂參考型別,支援單一繼承、多介面實作 |
interface | 合約定義,僅含簽章,不可實例化 |
delegate | 型別安全的函式指標,事件機制基石 |
string | 不可變字串,密封類別,值語意比較(== 比內容) |
array | 固定大小、同質元素集合,繼承自 System.Array |
interface ISerializable
{
void Serialize(Stream stream);
void Deserialize(Stream stream);
}
class UserProfile : ISerializable
{
public string Name { get; set; }
public void Serialize(Stream s) { /* ... */ }
public void Deserialize(Stream s) { /* ... */ }
}
// 介面參考存取
ISerializable serializer = new UserProfile();
serializer.Serialize(memoryStream);
delegate int Compare(T a, T b); // 泛型委派
class Sorter
{
public void Sort(T[] items, Compare comparer) { /* ... */ }
}
// 使用 Lambda 表達式
var sorter = new Sorter();
sorter.Sort(numbers, (a, b) => a.CompareTo(b));
string:不可變,+ 串接會建立新字串,高頻操作請用 StringBuilderint[] arr = {1,2,3};、多維 int[,] m = {{1,2},{3,4}};、交錯 int[][] j = new int[3][];值型別 → object(或介面),在堆疊配置物件並複製值。
int value = 2000;
object boxed = value; // Boxing 發生
boxed = 2001; // 修改 boxed 不影響 value
Console.WriteLine($"{value} {boxed}"); // 2000 2001
object → 值型別,執行期檢查型別正確性。
object boxed = 2000;
int unboxed = (int)boxed; // 正確
// double unboxed = (double)boxed; // 執行期拋出 InvalidCastException
ArrayList 存值型別)嚴重影響效能List<T>、泛型介面、避免裝箱decimal 專為金融設計,struct 適合小型不可變物件