C# (.NET) 中的对象序列化:从基础到高级技术
序列化是将复杂对象(类、结构体)转换为可保存到文件、通过网络传输或写入数据库的格式的过程。反向过程(从数据流中恢复对象)称为反序列化。在 .NET 平台中,有多种内置和第三方序列化工具,每种工具都有其特点、性能和应用场景。
在本文中,我们将介绍 C# 中主要的序列化方式:JSON(System.Text.Json 和 Newtonsoft.Json)、XML(XmlSerializer)、二进制序列化(BinaryFormatter——已过时但仍在使用)以及用于高性能场景的 Protocol Buffers(protobuf-net)。
1. 使用 System.Text.Json 进行 JSON 序列化
从 .NET Core 3.0 开始,Microsoft 推荐使用 System.Text.Json 命名空间处理 JSON。这是一个快速、底层且支持异步的 API。
序列化和反序列化示例:
using System;using System.Text.Json;
public class Person{ public string Name { get; set; } public int Age { get; set; } public string Email { get; set; }}
class Program{ static void Main() { var person = new Person { Name = "Ivan Petrov", Age = 30, Email = "ivan@example.com" };
// 序列化为 JSON 字符串 string jsonString = JsonSerializer.Serialize(person); Console.WriteLine(jsonString); // 输出:{"Name":"Ivan Petrov","Age":30,"Email":"ivan@example.com"}
// 从 JSON 反序列化 string jsonInput = @"{""Name"":""Maria"",""Age"":25,""Email"":""maria@test.ru""}"; Person restoredPerson = JsonSerializer.Deserialize<Person>(jsonInput); Console.WriteLine($"Name: {restoredPerson.Name}, Age: {restoredPerson.Age}"); }}序列化配置:
- 忽略 null 属性:
JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull } - 格式化输出(pretty print):
JsonSerializerOptions { WriteIndented = true } - 处理循环引用:
ReferenceHandler.Preserve
2. Newtonsoft.Json (Json.NET) —— 经典方案
在 System.Text.Json 出现之前,Newtonsoft.Json 库(通过 NuGet 安装)是事实上的标准。它支持更多场景:动态对象、属性、转换器和灵活的配置。
using Newtonsoft.Json;
public class Order{ public int Id { get; set; } public decimal Amount { get; set; } [JsonIgnore] public string InternalNote { get; set; } // 此字段不会被序列化}
var order = new Order { Id = 1, Amount = 99.99m, InternalNote = "Secret" };string json = JsonConvert.SerializeObject(order, Formatting.Indented);Console.WriteLine(json);// {// "Id": 1,// "Amount": 99.99// }
var deserialized = JsonConvert.DeserializeObject<Order>(json);3. XML 序列化 (XmlSerializer)
对于 XML 格式,.NET 使用 XmlSerializer 类。它非常适合与遗留系统和 SOAP 服务兼容。
using System;using System.IO;using System.Xml.Serialization;
[Serializable]public class Product{ [XmlAttribute] public int Id { get; set; } [XmlElement("ProductName")] public string Name { get; set; }}
class Program{ static void Main() { var product = new Product { Id = 42, Name = "Laptop" };
// 序列化