CodeGym /課程 /C# SELF /.NET 中標準序列化類別概覽

.NET 中標準序列化類別概覽

C# SELF
等級 44 , 課堂 0
開放

1. 介紹

既然我們決定把「LEGO 人偶拆解成零件」,那就來看看在 .NET 裡有哪些工具可以用。換句話說 —— 有哪些標準類別幫助我們把物件序列化和反序列化成不同格式,每種背後的原理是什麼。

.NET 序列化家族的構成

在當前(2025)階段,.NET 提供了幾個主要的序列化方法,每個方法都有自己的一套類別和工具。主要且最常見的有:

  • JSON 序列化 — 最主要、最現代的選擇,在大多數專案中使用。
  • XML 序列化 — 稍微老派一些,但仍被廣泛使用。
  • 二進位序列化 — 只在特殊情況下使用,通常透過現代的第三方方案實現。

很多範例和大量 .NET 9 的程式碼都使用 JSON,這不是一時的流行 —— 而是產業標準。但 .NET 同時也支援其他方式,以備不時之需。

.NET 序列化的主角們

格式 序列化類別 簡單程度 效能 安全性 當前性
JSON
System.Text.Json
🔥🔥🔥 🔥🔥🔥 🔥🔥🔥 最為現代
XML
System.Xml.Serialization.XmlSerializer
🔥🔥 🔥🔥 🔥🔥 仍在使用
JSON Newtonsoft.Json (Json.NET) 🔥🔥🔥 🔥🔥 🔥🔥🔥 非常受歡迎

各自簡介

  • System.Text.Json:.NET 的新標準 JSON 序列化器,從 .NET Core 3.0 出現,並在 .NET 5+ 成為主要選擇。快速、輕量、安全,並且在 .NET 9 中是開箱即用的。 文件
  • XmlSerializer:序列化到 XML 的老牌方案。使用簡單,但有一些限制(例如需要 public 類與公開屬性)。適合需要相容性和嚴格資料契約的場景。 文件
  • Newtonsoft.Json:在 System.Text.Json 出現之前長期是 JSON 序列化的事實標準。常用於複雜場景(像是動態資料、私有屬性等)。 文件

BinaryFormatter 到哪去了?

如果你在網路上看到建議使用 BinaryFormatter —— 那大概是很老的教學了。不要使用 BinaryFormatter:它已經在 .NET 9 中移除,原因是安全性問題。現代的二進位序列化通常由第三方方案提供,例如 ProtobufMessagePack

2. 簡單範例

現在把序列化和反序列化用實作展示出來,我們用已經熟悉的遊戲世界類別 Player 作為例子。

準備要序列化的類別

// Player.cs
public class Player
{
    public string Name { get; set; }
    public int Health { get; set; }
    public bool IsAlive { get; set; }
    public List<string> Inventory { get; set; }
    public Position Position { get; set; }
}

public class Position
{
    public int X { get; set; }
    public int Y { get; set; }
}

a) 使用 System.Text.Json 做 JSON 序列化與反序列化

using System.Text.Json;

Player aragorn = new Player
{
    Name = "Aragorn",
    Health = 100,
    IsAlive = true,
    Inventory = new List<string> { "sword", "bow", "healing potion" },
    Position = new Position { X = 10, Y = 25 }
};

// 將 Player 物件序列化成 JSON 字串
string json = JsonSerializer.Serialize(aragorn);
// 輸出 JSON 到控制台
Console.WriteLine(json);

// 將 JSON 字串反序列化回 Player 物件
Player? aragornClone = JsonSerializer.Deserialize<Player>(json);
// 檢查克隆是否有效 :)
Console.WriteLine(aragornClone?.Name); // 應該輸出 "Aragorn"

就是這麼簡單 —— 不需要任何「舞刀弄棒」或魔法屬性。接著看一下 XML 的寫法。

b) 使用 XmlSerializer 做 XML 序列化與反序列化

using System.Xml.Serialization;

// 為 Player 類別建立序列化器
XmlSerializer serializer = new XmlSerializer(typeof(Player));

// 序列化到檔案
using FileStream fs = new FileStream("aragorn.xml", FileMode.Create);
serializer.Serialize(fs, aragorn); // 把 Aragorn 存到 XML 檔

// 從檔案反序列化
using FileStream fs = new FileStream("aragorn.xml", FileMode.Open);
Player aragornFromXml = (Player) serializer.Deserialize(fs)!;
Console.WriteLine(aragornFromXml.Name); // 應該輸出 "Aragorn"

注意!XmlSerializer 要求類別和其屬性是 公開的,並且要有無參構造函式(如果你覆寫了構造函式,請保留一個 public 且沒有參數的構造函式)。否則序列化會失敗。

c) 使用 Newtonsoft.Json 做 JSON 序列化與反序列化

using Newtonsoft.Json; // 別忘了透過 NuGet 加入 Newtonsoft.Json 套件!

// 序列化
string json2 = JsonConvert.SerializeObject(aragorn);

// 反序列化
Player? aragornFromNewtonsoft = JsonConvert.DeserializeObject<Player>(json2);

Console.WriteLine(aragornFromNewtonsoft?.Name); // 又是 "Aragorn"

寫法看起來幾乎一樣,但 Newtonsoft.Json 提供大量額外選項 —— 例如可以序列化私有欄位、調整格式化、處理複雜場景等。

4. 實用細節

標準序列化器和它們的能力

類別 格式 是否內建於 .NET 是否需要 NuGet 套件? 適合用於檔案嗎 適合用於 API 嗎 簡單程度
System.Text.Json
JSON 輕量
Newtonsoft.Json
JSON 輕量
XmlSerializer
XML 常用 輕量

如何選擇要使用哪個類別?

如果你不知道為什麼需要 XML —— 幾乎總是選 JSON 和 System.Text.Json。它更快、更簡單,並且符合現代實務。

XML 適合當:

  • 你要和舊系統整合,對方只接受 XML。
  • 你需要嚴格的 schema 和資料結構驗證。
  • 結構固定且穩定,且形式相容性很重要(設定、配置、與企業系統交換)。

JSON 適合當:

  • 你在做現代應用,與 web 或行動裝置互動。
  • 你需要簡單、可讀且緊湊的格式。
  • 你不想引入額外的依賴。

Newtonsoft.Json 適合當:

  • 你需要序列化私有欄位、特殊的自訂化,或完全的彈性。
  • 或者你的專案已經在使用這個庫,現在遷移不划算。

5. 常見錯誤與陷阱

編碼。 主要序列化類別(尤其是處理檔案時)通常使用 UTF-8。如果看到亂碼,請檢查你是如何讀寫檔案以及是否明確設定了編碼。設定編碼的文件

不支援的類型。 某些標準序列化器(特別是 XML)無法序列化像字典(Dictionary)、私有/受保護欄位、事件、delegate 和介面這類類型。通常只支援公開的簡單屬性與類別。

類別版本差異。 如果你更改了類別結構(新增/重新命名/刪除屬性),舊的已儲存資料可能無法正確讀取或反序列化。要規劃格式的版本管理。

Null 值。 反序列化時,如果資料中缺少某個欄位,對應的屬性會取得預設值(對於參考型別是 null)。記得做好檢查。

屬性標註(attributes)。 要做精細控制常用像 [JsonIgnore][XmlElement] 這類屬性。它們可以排除屬性、改變元素名稱或控制格式——詳細內容會在後續講座討論。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION