基於 XmlSerializer 封裝通用泛型序列化/反序列化方法,支援陣列、List、單物件,簡化配置檔、快取、訊息隊列等場景的 XML 持久化操作。
public static class Serializer {
// === 序列化 ===
public static void Serialize<T>(string filePath, T[] array) where T : new() {
if (string.IsNullOrEmpty(filePath) || array == null || array.Length == 0) return;
try {
var factory = new XmlSerializerFactory();
var serializer = factory.CreateSerializer(array.GetType(), typeof(T).Name);
using (var stream = new FileStream(filePath, FileMode.Create))
serializer.Serialize(stream, array);
} catch { /* 建議記錄日誌 */ }
}
public static void Serialize(string filePath, object obj) {
if (string.IsNullOrEmpty(filePath) || obj == null) return;
try {
var factory = new XmlSerializerFactory();
var serializer = factory.CreateSerializer(obj.GetType(), obj.GetType().Name);
using (var stream = new FileStream(filePath, FileMode.Create))
serializer.Serialize(stream, obj);
} catch { }
}
// === 反序列化 ===
public static List<T> Deserialize<T>(string filePath) where T : new() {
var results = new List<T>();
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath)) return results;
try {
var factory = new XmlSerializerFactory();
var serializer = factory.CreateSerializer(typeof(T[]), typeof(T).Name);
using (var stream = new FileStream(filePath, FileMode.Open)) {
var obj = serializer.Deserialize(stream);
results.AddRange((T[])obj);
}
} catch { }
return results;
}
public static object Deserialize(string filePath, Type targetType) {
if (string.IsNullOrEmpty(filePath) || !File.Exists(filePath) || targetType == null) return null;
try {
var factory = new XmlSerializerFactory();
var serializer = factory.CreateSerializer(targetType, targetType.Name);
using (var stream = new FileStream(filePath, FileMode.Open))
return serializer.Deserialize(stream);
} catch { return null; }
}
}
// 實體類
public class ConfigItem { public string Key { get; set; } public string Value { get; set; } }
// 序列化陣列
var items = new[] { new ConfigItem { Key="A", Value="1" }, new ConfigItem { Key="B", Value="2" } };
Serializer.Serialize("config.xml", items);
// 反序列化為 List
var list = Serializer.Deserialize<ConfigItem>("config.xml");
// 單物件序列化/反序列化
var settings = new AppSettings { Theme="Dark", Lang="zh-TW" };
Serializer.Serialize("settings.xml", settings);
var loaded = (AppSettings)Serializer.Deserialize("settings.xml", typeof(AppSettings));
XmlSerializerFactory:緩存序列化器組件,避免重複動態生成導致記憶體洩漏(.NET 4.5+ 建議直接用 new XmlSerializer(type),內建快取)。typeof(T[]) vs typeof(T).Name:反序列化陣列需傳入陣列型別,根元素名稱用類型名。where T : new():確保無參構造函式存在,XmlSerializer 要求。Stream、TextWriter、XmlWriter 多重輸出目標。XmlWriterSettings(縮排、編碼、命名空間控制)。XmlRoot、XmlElement 屬性自定義 XML 結構。IXmlSerializable 完全控制讀寫邏輯(大數據流式處理)。| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
XmlSerializer | 標準、支援屬性控制、Schema 驗證 | 僅公共屬性/欄位、需無參構造、效能一般 | 配置檔、小型數據交換 |
DataContractSerializer | WCF 預設、支援私有欄位、版本容錯、效能優 | 需 [DataMember]、無 XML 屬性控制 | 服務契約、大型物件圖 |
Json.NET | 極快、彈性、LINQ to JSON、廣泛生態 | 非 XML 格式 | Web API、NoSQL、日誌 |
protobuf-net | 二進位、極小、極快、Schema 演進 | 非人類可讀、需定義 .proto 或屬性 | 高效能 RPC、快取、訊息隊列 |