首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 型別系統完全指南:值型別、參考型別與 Boxing/Unboxing

     編輯:關於C語言

第四章 C# 型別系統:強型別語言的基石

C# 是強型別語言,每個變數、常數、運算式皆有明確型別。理解值/參考型別差異、Boxing/Unboxing 機制,是寫出高效、正確程式的關鍵。

4.1 值型別:直接包含資料

值型別變數直接儲存資料本身,指派時會複製值。分類如下:

4.1.1 簡單型別

對應 .NET 系統型別別名,支援常數運算式編譯期求值,可用常值初始化。

分類C# 關鍵字.NET 型別範圍/精度
整數sbyteSystem.SByte有號 8-bit:-128 ~ 127
byteSystem.Byte無號 8-bit:0 ~ 255
shortSystem.Int16有號 16-bit:-32,768 ~ 32,767
ushortSystem.UInt16無號 16-bit:0 ~ 65,535
intSystem.Int32有號 32-bit:-2,147,483,648 ~ 2,147,483,647
uintSystem.UInt32無號 32-bit:0 ~ 4,294,967,295
longSystem.Int64有號 64-bit:±9.22×10¹⁸
ulongSystem.UInt64無號 64-bit:0 ~ 1.84×10¹⁹
charSystem.CharUTF-16 字元(16-bit)
布林boolSystem.Booleantrue/false,不可隱式轉換整數
浮點floatSystem.Single±1.5×10⁻⁴⁵ ~ ±3.4×10³⁸,7 位精度
doubleSystem.Double±5.0×10⁻³²⁴ ~ ±1.7×10³⁰⁸,15-16 位精度
十進位decimalSystem.Decimal128-bit,28-29 位有效數字,適合金融計算

關鍵差異提醒

  • int/long 大小固定,不隨平台變化(不同於 C/C++)
  • bool 僅接受 true/false,if (x = 1) 會編譯錯誤
  • char 為 UTF-16,無隱式轉換至數值型別,需強制轉型
  • decimal 無隱式轉換至/自 double,避免精度遺失/溢位

4.1.2 結構型別

關鍵字 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 友善。

4.1.3 列舉型別

定義具名常數集合,底層為整數型別(預設 int)。


enum Month : byte { Jan = 1, Feb, Mar, Apr }  // 指定底層型別與起始值
enum Flags { None = 0, Read = 1, Write = 2, Execute = 4 }  // 位旗標

4.2 參考型別:儲存資料位址

參考型別變數儲存物件參考,指派時複製參考,多個變數可指向同一物件。

型別說明
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:不可變,+ 串接會建立新字串,高頻操作請用 StringBuilder
  • 陣列:int[] arr = {1,2,3};、多維 int[,] m = {{1,2},{3,4}};、交錯 int[][] j = new int[3][];

4.3 Boxing 與 Unboxing:值型別與物件的橋樑

Boxing(隱式)

值型別 → object(或介面),在堆疊配置物件並複製值。


int value = 2000;
object boxed = value;  // Boxing 發生
boxed = 2001;          // 修改 boxed 不影響 value
Console.WriteLine($"{value} {boxed}");  // 2000 2001

Unboxing(顯式)

object → 值型別,執行期檢查型別正確性。


object boxed = 2000;
int unboxed = (int)boxed;  // 正確

// double unboxed = (double)boxed;  // 執行期拋出 InvalidCastException

效能影響

  • Boxing 配置堆疊記憶體,增加 GC 壓力
  • 頻繁 Boxing/Unboxing(如非泛型集合 ArrayList 存值型別)嚴重影響效能
  • 解決方案:使用泛型集合 List<T>、泛型介面、避免裝箱

本章小結

  • 值型別:簡單型別、結構、列舉——直接儲存資料,指派複製值
  • 參考型別:類別、介面、委派、字串、陣列——儲存參考,指派複製參考
  • decimal 專為金融設計,struct 適合小型不可變物件
  • Boxing/Unboxing 連接兩大體系,但有效能成本,泛型可大幅減少需求
  • 下一章將深入探討 C# 最核心的型別——類別
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved