在 C# 中,对 包含嵌套类的类进行 XML 序列化和反序列化 是一个常见需求,尤其在处理复杂对象结构时。为了确保嵌套类能够被正确地序列化和反序列化,我们需要遵循一些基本规则,并使用适当的特性(Attributes)来控制序列化行为。
✅ 一、基本要求
在进行 XML 序列化时,以下几点是必须满足的:
条件 | 说明 |
---|---|
无参数构造函数 | 所有参与序列化的类(包括嵌套类)都必须有无参数构造函数。 |
公共属性或字段 | XML 序列化默认只处理 public 的属性或字段。 |
嵌套类也需要可序列化 | 嵌套类本身也必须满足上述条件,才能被正确序列化。 |
📌 二、XML 序列化嵌套类的示例
1. 定义包含嵌套类的类
csharp
using System;
using System.Xml.Serialization;
[XmlRoot("Person")]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
// 嵌套类
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
2. 序列化为 XML 文件
csharp
using System;
using System.IO;
using System.Xml.Serialization;
class Program
{
static void Main()
{
Person person = new Person
{
Name = "Alice",
Age = 25,
Address = new Address
{
Street = "123 Main St",
City = "New York"
}
};
XmlSerializer serializer = new XmlSerializer(typeof(Person));
using (StreamWriter writer = new StreamWriter("person.xml"))
{
serializer.Serialize(writer, person);
}
Console.WriteLine("对象已成功序列化为 XML 文件。");
}
}
3. 反序列化 XML 文件为对象
csharp
class Program
{
static void Main()
{
string filePath = "person.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Person));
using (StreamReader reader = new StreamReader(filePath))
{
Person person = (Person)serializer.Deserialize(reader);
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
Console.WriteLine($"Address: {person.Address.Street}, {person.Address.City}");
}
}
}
🧩 三、处理集合类(如 List)
如果类中包含集合类(如 List<Address>
),可以使用 [XmlArray]
和 [XmlArrayItem]
来控制集合的序列化格式。
示例结构
csharp
[XmlRoot("Person")]
public class Person
{
public string Name { get; set; }
[XmlArray("Addresses")]
[XmlArrayItem("Address")]
public List<Address> Addresses { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
输出 XML 示例
xml
<Person>
<Name>Alice</Name>
<Addresses>
<Address>
<Street>123 Main St</Street>
<City>New York</City>
</Address>
<Address>
<Street>456 Oak St</Street>
<City>Los Angeles</City>
</Address>
</Addresses>
</Person>
⚠️ 四、常见问题与解决方案
问题 | 原因 | 解决方案 |
---|---|---|
无法序列化嵌套类 | 嵌套类没有默认构造函数 | 添加无参数构造函数 |
字段未序列化 | 字段是 private 或未标记 |
使用 [XmlElement] 显式标记 |
集合类未序列化 | 没有使用 [XmlArray] 或 [XmlArrayItem] |
添加集合序列化特性 |
序列化失败 | 类中包含接口或抽象类 | 使用 [XmlElement] 或自定义 XmlType |
命名空间冲突 | 默认命名空间自动添加 | 使用 [XmlRoot(Namespace = "...")] 控制命名空间 |
📌 五、总结
步骤 | 操作 |
---|---|
1 | 确保类和嵌套类都有无参数构造函数 |
2 | 使用 [XmlElement] 控制字段/属性的 XML 元素名称 |
3 | 使用 [XmlArray] 和 [XmlArrayItem] 控制集合类的序列化 |
4 | 使用 XmlSerializer.Serialize() 进行序列化 |
5 | 使用 XmlSerializer.Deserialize() 进行反序列化 |
通过上述方法,你可以轻松实现包含嵌套类或集合类的复杂对象的 XML 序列化和反序列化。只要确保嵌套类也满足序列化要求,就可以实现结构清晰、数据完整的 XML 文件读写。