序列化 #

一、序列化概述 #

1.1 什么是序列化 #

序列化是将对象转换为可存储或传输的格式的过程,反序列化是逆向过程。

1.2 序列化类型 #

类型 说明
JSON 轻量级,Web常用
XML 结构化,可读性好
二进制 高效,.NET专用

二、JSON序列化 #

2.1 System.Text.Json #

csharp
using System.Text.Json;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Email { get; set; }
}

var person = new Person { Name = "张三", Age = 25, Email = "test@example.com" };

string json = JsonSerializer.Serialize(person);
Console.WriteLine(json);

Person? deserialized = JsonSerializer.Deserialize<Person>(json);

2.2 序列化选项 #

csharp
var options = new JsonSerializerOptions
{
    WriteIndented = true,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    PropertyNameCaseInsensitive = true,
    Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};

string json = JsonSerializer.Serialize(person, options);
Person? obj = JsonSerializer.Deserialize<Person>(json, options);

2.3 文件读写 #

csharp
public static async Task SaveAsync<T>(string path, T data)
{
    var options = new JsonSerializerOptions { WriteIndented = true };
    await using var stream = File.Create(path);
    await JsonSerializer.SerializeAsync(stream, data, options);
}

public static async Task<T?> LoadAsync<T>(string path)
{
    await using var stream = File.OpenRead(path);
    return await JsonSerializer.DeserializeAsync<T>(stream);
}

2.4 JsonPropertyName #

csharp
public class User
{
    [JsonPropertyName("id")]
    public int Id { get; set; }
    
    [JsonPropertyName("user_name")]
    public string UserName { get; set; }
    
    [JsonIgnore]
    public string Password { get; set; }
}

var user = new User { Id = 1, UserName = "zhangsan", Password = "secret" };
string json = JsonSerializer.Serialize(user);

2.5 自定义转换器 #

csharp
public class DateTimeConverter : JsonConverter<DateTime>
{
    private const string Format = "yyyy-MM-dd HH:mm:ss";
    
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return DateTime.ParseExact(reader.GetString(), Format, null);
    }
    
    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString(Format));
    }
}

var options = new JsonSerializerOptions();
options.Converters.Add(new DateTimeConverter());

三、XML序列化 #

3.1 XmlSerializer #

csharp
using System.Xml.Serialization;

[XmlRoot("Person")]
public class Person
{
    [XmlElement("Name")]
    public string Name { get; set; }
    
    [XmlElement("Age")]
    public int Age { get; set; }
    
    [XmlAttribute("Id")]
    public int Id { get; set; }
}

var person = new Person { Id = 1, Name = "张三", Age = 25 };

var serializer = new XmlSerializer(typeof(Person));
using var writer = new StreamWriter("person.xml");
serializer.Serialize(writer, person);

using var reader = new StreamReader("person.xml");
var deserialized = (Person)serializer.Deserialize(reader);

3.2 XML特性 #

csharp
[XmlRoot("Order", Namespace = "http://example.com/order")]
public class Order
{
    [XmlAttribute("id")]
    public int Id { get; set; }
    
    [XmlElement("Customer")]
    public string Customer { get; set; }
    
    [XmlArray("Items")]
    [XmlArrayItem("Item")]
    public List<OrderItem> Items { get; set; }
    
    [XmlIgnore]
    public decimal Total => Items.Sum(i => i.Price * i.Quantity);
}

public class OrderItem
{
    [XmlElement("Product")]
    public string Product { get; set; }
    
    [XmlElement("Price")]
    public decimal Price { get; set; }
    
    [XmlElement("Quantity")]
    public int Quantity { get; set; }
}

3.3 XML辅助方法 #

csharp
public static class XmlHelper
{
    public static string Serialize<T>(T obj)
    {
        var serializer = new XmlSerializer(typeof(T));
        using var writer = new StringWriter();
        serializer.Serialize(writer, obj);
        return writer.ToString();
    }
    
    public static T? Deserialize<T>(string xml)
    {
        var serializer = new XmlSerializer(typeof(T));
        using var reader = new StringReader(xml);
        return (T?)serializer.Deserialize(reader);
    }
    
    public static void SaveToFile<T>(string path, T obj)
    {
        var serializer = new XmlSerializer(typeof(T));
        using var writer = new StreamWriter(path);
        serializer.Serialize(writer, obj);
    }
    
    public static T? LoadFromFile<T>(string path)
    {
        var serializer = new XmlSerializer(typeof(T));
        using var reader = new StreamReader(path);
        return (T?)serializer.Deserialize(reader);
    }
}

四、二进制序列化 #

4.1 BinaryFormatter(已过时) #

csharp
[Obsolete("BinaryFormatter已过时,建议使用其他方案")]
public static void SaveBinary<T>(string path, T obj)
{
    using var stream = File.Create(path);
    var formatter = new BinaryFormatter();
    formatter.Serialize(stream, obj);
}

4.2 MessagePack #

csharp
using MessagePack;

[MessagePackObject]
public class Person
{
    [Key(0)]
    public string Name { get; set; }
    
    [Key(1)]
    public int Age { get; set; }
}

var person = new Person { Name = "张三", Age = 25 };
byte[] bytes = MessagePackSerializer.Serialize(person);
Person? deserialized = MessagePackSerializer.Deserialize<Person>(bytes);

五、实战示例 #

5.1 配置管理 #

csharp
public class AppConfig
{
    public string AppName { get; set; } = "MyApp";
    public string Version { get; set; } = "1.0.0";
    public Dictionary<string, string> Settings { get; set; } = new();
    
    private static readonly string ConfigPath = "config.json";
    
    public static AppConfig Load()
    {
        if (!File.Exists(ConfigPath))
            return new AppConfig();
        
        var json = File.ReadAllText(ConfigPath);
        return JsonSerializer.Deserialize<AppConfig>(json) ?? new AppConfig();
    }
    
    public void Save()
    {
        var options = new JsonSerializerOptions { WriteIndented = true };
        var json = JsonSerializer.Serialize(this, options);
        File.WriteAllText(ConfigPath, json);
    }
}

5.2 数据持久化 #

csharp
public class Repository<T> where T : class
{
    private readonly string _filePath;
    
    public Repository(string fileName)
    {
        _filePath = fileName;
    }
    
    public List<T> LoadAll()
    {
        if (!File.Exists(_filePath))
            return new List<T>();
        
        var json = File.ReadAllText(_filePath);
        return JsonSerializer.Deserialize<List<T>>(json) ?? new List<T>();
    }
    
    public void SaveAll(List<T> items)
    {
        var options = new JsonSerializerOptions { WriteIndented = true };
        var json = JsonSerializer.Serialize(items, options);
        File.WriteAllText(_filePath, json);
    }
    
    public void Add(T item)
    {
        var items = LoadAll();
        items.Add(item);
        SaveAll(items);
    }
}

六、总结 #

序列化要点:

格式 特点
JSON JsonSerializer 轻量、Web友好
XML XmlSerializer 结构化、可读
二进制 MessagePack 高效、紧凑

下一步,让我们学习多线程!

最后更新:2026-03-26