You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#使用XmlSerializer序列化Student类反序列化为List报错解决方案问询

问题根源
  • 格式不匹配:你使用XmlSerializer生成的是XML格式数据,并非CSV格式,文件后缀命名错误。
  • 成员可访问性错误:Student类的字段均为私有级别,XmlSerializer默认仅支持序列化公共成员,无法正确读写私有字段。
  • 集合操作逻辑错误:List<Student>是集合类型,不能直接为集合设置studentID等属性,需要先实例化单个Student对象再添加到集合中。
  • 序列化写入逻辑错误:你采用追加模式每次写入单个Student对象,每次序列化都会自动生成XML声明节点,导致最终文件存在多个XML声明,不符合XML语法规范,因此反序列化抛出异常。
  • 类型匹配错误:studentID为int类型,不能直接赋值文本框的字符串内容,需要做类型转换。

修复方案

关于你提到的XmlWriter.Create方案:如果确实需要用该方法追加写入单个节点,需要手动移除每次生成的XML声明,并且自定义统一根节点包裹所有Student元素,实现复杂度远高于下方推荐方案,不建议使用。

方案1:修正XML序列化逻辑(适合需要XML格式的场景)

第一步:修正Student类定义

[Serializable]
public class Student
{
    // 改为公共字段,也可加[XmlElement]特性修饰私有字段
    public int studentID;
    public string studentName;
    public string studentAge;
}

第二步:正确序列化逻辑

直接序列化List<Student>集合类型,每次写入覆盖整个文件,避免多XML声明问题:

// 1. 构造新的Student对象
Student newStudent = new Student()
{
    studentID = int.Parse(txt_sID.Text),
    studentName = txt_sName.Text,
    studentAge = txt_sAge.Text
};
// 2. 读取现有集合数据(如果文件存在)
List<Student> students = new List<Student>();
string filePath = @"students.xml"; // 后缀改为xml匹配格式
if (File.Exists(filePath))
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open))
    {
        XmlSerializer listSerializer = new XmlSerializer(typeof(List<Student>));
        students = (List<Student>)listSerializer.Deserialize(fs);
    }
}
// 3. 添加新对象到集合并全量写入文件
students.Add(newStudent);
using (TextWriter writer = new StreamWriter(filePath))
{
    XmlSerializer listSerializer = new XmlSerializer(typeof(List<Student>));
    listSerializer.Serialize(writer, students);
}

第三步:反序列化逻辑

List<Student> students = new List<Student>();
string filePath = @"students.xml";
if (File.Exists(filePath))
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open))
    {
        XmlSerializer listSerializer = new XmlSerializer(typeof(List<Student>));
        students = (List<Student>)listSerializer.Deserialize(fs);
    }
}

方案2:真实CSV序列化方案(更适合轻量列表存储)

CSV格式无复杂节点,读写性能更好,适合扁平类数据存储,完全匹配你最初的文件格式需求:

写入逻辑

Student newStudent = new Student()
{
    studentID = int.Parse(txt_sID.Text),
    studentName = txt_sName.Text,
    studentAge = txt_sAge.Text
};
string filePath = @"students.csv";
// 首次写入添加表头,后续仅追加数据
bool needHeader = !File.Exists(filePath);
using (StreamWriter sw = new StreamWriter(filePath, true, Encoding.UTF8))
{
    if (needHeader)
    {
        sw.WriteLine("studentID,studentName,studentAge");
    }
    // 处理含逗号、双引号的特殊字段,用双引号包裹
    sw.WriteLine($"{newStudent.studentID},\"{newStudent.studentName.Replace("\"", "\"\"")}\",{newStudent.studentAge}");
}

读取逻辑

List<Student> students = new List<Student>();
string filePath = @"students.csv";
if (File.Exists(filePath))
{
    string[] lines = File.ReadAllLines(filePath, Encoding.UTF8);
    // 跳过表头行
    for (int i = 1; i < lines.Length; i++)
    {
        string line = lines[i].Trim();
        if (string.IsNullOrEmpty(line)) continue;
        string[] parts = line.Split(',');
        students.Add(new Student()
        {
            studentID = int.Parse(parts[0].Trim()),
            studentName = parts[1].Trim('"').Replace("\"\"", "\""),
            studentAge = parts[2].Trim()
        });
    }
}

内容的提问来源于stack exchange,提问作者ItsDano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 05:06:04