# C# 对象的序列化与反序列化 ## 1. 什么是序列化? **序列化(Serialization)** 是指将对象的状态信息转换为可以存储或传输的形式(例如字节流、文件、内存数据)的过程。 反之,**反序列化(Deserialization)** 则是将存储或传输的序列化数据还原为对象的过程。 在 C# 中,最常用的方式是通过 `BinaryFormatter` 类来完成二进制序列化与反序列化。 --- ## 2. 核心类与方法 - **BinaryFormatter.Serialize(Stream, object)** 将对象序列化到指定的流中。 - **BinaryFormatter.Deserialize(Stream)** 从指定的流中反序列化对象。 > ⚠️ 注意:从 .NET 5 开始,官方已经不推荐使用 `BinaryFormatter`(存在安全风险),更推荐 `System.Text.Json` 或 `XmlSerializer` 等。但在学习和理解基础时,仍可使用。 --- ## 3. 序列化方式 ### 3.1 文件流方式 通过 **文件流(FileStream)** 将对象直接保存到文件中。 ``` csharp using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable] // 必须标记为可序列化 public class Person { public string Name; public int Age; } class Program { static void Main() { Person p = new Person { Name = "Tom", Age = 25 }; // 序列化到文件 using (FileStream fs = new FileStream("person.dat", FileMode.Create)) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fs, p); } Console.WriteLine("对象已序列化到文件 person.dat"); } } ``` ### 3.2 内存流方式 通过 **内存流(MemoryStream)** 将对象序列化成字节数组,便于网络传输或自定义存储。 ``` csharp using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable] public class Person { public string Name; public int Age; } class Program { static void Main() { Person p = new Person { Name = "Alice", Age = 30 }; byte[] buffer; // 序列化到内存流 using (MemoryStream ms = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(ms, p); buffer = ms.ToArray(); // 获取字节数组 } // 可以将字节数组写入文件或通过网络传输 File.WriteAllBytes("person_bytes.dat", buffer); Console.WriteLine("对象已序列化为字节数组并写入 person_bytes.dat"); } } ``` --- ## 4. 反序列化 ### 4.1 从文件反序列化 ``` csharp using (FileStream fs = new FileStream("person.dat", FileMode.Open)) { BinaryFormatter formatter = new BinaryFormatter(); Person p = (Person)formatter.Deserialize(fs); Console.WriteLine($"Name: {p.Name}, Age: {p.Age}"); } ``` ### 4.2 从字节数组反序列化 ``` csharp byte[] buffer = File.ReadAllBytes("person_bytes.dat"); using (MemoryStream ms = new MemoryStream(buffer)) { BinaryFormatter formatter = new BinaryFormatter(); Person p = (Person)formatter.Deserialize(ms); Console.WriteLine($"Name: {p.Name}, Age: {p.Age}"); } ``` --- ## 5. 注意事项 - **必须添加 `[Serializable]` 特性** 否则对象无法被序列化。 - **字段级别的控制** 如果某些字段不想被序列化,可以使用 `[NonSerialized]` 特性修饰。 ``` csharp [NonSerialized] private string password; ``` - **安全问题** `BinaryFormatter` 在反序列化时可能存在安全漏洞,不适合用于处理不受信任的数据。 - **替代方案** - 文本序列化(如 `JsonSerializer`、`XmlSerializer`) - 跨平台高性能方案(如 `MessagePack`、`Protobuf`) --- ## 6. 总结 - **文件流序列化**:直接将对象保存到磁盘文件中。 - **内存流序列化**:对象 → 字节数组 → 可保存或传输。 - **反序列化**:根据文件流或字节数组还原对象。 序列化与反序列化是 C# 中对象持久化与数据传输的核心知识点,实际开发中需结合安全性与场景选择合适的序列化方式。