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

泛型序列化工具箱:XmlSerializer 實現 XML 與物件陣列/單物件雙向轉換

     編輯:關於ASP.NET

基於 XmlSerializer 封裝通用泛型序列化/反序列化方法,支援陣列、List、單物件,簡化配置檔、快取、訊息隊列等場景的 XML 持久化操作。

核心静態類:Serializer

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 驗證僅公共屬性/欄位、需無參構造、效能一般配置檔、小型數據交換
DataContractSerializerWCF 預設、支援私有欄位、版本容錯、效能優需 [DataMember]、無 XML 屬性控制服務契約、大型物件圖
Json.NET極快、彈性、LINQ to JSON、廣泛生態非 XML 格式Web API、NoSQL、日誌
protobuf-net二進位、極小、極快、Schema 演進非人類可讀、需定義 .proto 或屬性高效能 RPC、快取、訊息隊列
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved