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

C#中读取含向量属性的Student类对象的技术实现问询

解决方案:从文件读取带向量属性的C# Student类对象

嘿,针对你的Student类(包含私有数组note、readonly字段、const和静态成员),我整理了几种靠谱的从文件读取对象的方案,每种都附代码示例,你可以根据自己的场景选:

方案1:使用System.Text.Json(.NET Core/.NET 5+ 原生推荐)

首先,我们需要调整Student类,确保序列化器能处理私有字段、readonly成员和构造函数:

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

// 假设基类是这样的(你需要确保基类也支持序列化)
public class Person
{
    public string Cnp { get; }
    public string Nume { get; }

    public Person(string cnp, string nume)
    {
        Cnp = cnp;
        Nume = nume;
    }
}

public class Student : Person
{
    private int[] note;//分数向量
    private DateTime dataInrolarii;
    private int nrRestante;
    private readonly int nrMatricol;
    private const string sex = "feminin";
    public static int anStudiu = 3;

    // 标记这个构造函数用于反序列化
    [JsonConstructor]
    public Student(string cnp, string nume, int nrMatricol, DateTime dataInrolarii, int nrRestante, int[] note) 
        : base(cnp, nume)
    {
        this.nrMatricol = nrMatricol;
        this.dataInrolarii = dataInrolarii;
        this.nrRestante = nrRestante;
        this.note = note ?? Array.Empty<int>();
    }

    // 可选:添加属性用于暴露私有字段(如果需要)
    public int[] Note => note;
    public DateTime DataInrolarii => dataInrolarii;
    public int NrRestante => nrRestante;
    public int NrMatricol => nrMatricol;
}

然后是序列化到文件和读取的代码:

// 序列化学生对象到文件
var student = new Student(
    "1234567890123",
    "Maria Popescu",
    12345,
    new DateTime(2021, 9, 1),
    0,
    new int[] { 9, 10, 8 });

var options = new JsonSerializerOptions
{
    IncludeFields = true, // 序列化私有字段
    WriteIndented = true, // 格式化输出,方便阅读
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor // 确保构造函数能被访问
};

string json = JsonSerializer.Serialize(student, options);
File.WriteAllText("student.json", json);

// 从文件读取并反序列化
string jsonFromFile = File.ReadAllText("student.json");
Student loadedStudent = JsonSerializer.Deserialize<Student>(jsonFromFile, options);

// 验证读取结果
Console.WriteLine($"学生姓名:{loadedStudent.Nume}");
Console.WriteLine($"分数:{string.Join(", ", loadedStudent.Note)}");

注意:const string sex是编译时常量,不需要序列化;static int anStudiu是静态成员,默认不会被序列化(静态成员属于类而非实例),如果需要保存静态状态,得手动处理。

方案2:使用Newtonsoft.Json(Json.NET,兼容性更强)

如果是.NET Framework项目,或者需要更灵活的序列化配置,Json.NET是很好的选择:

using Newtonsoft.Json;

// 同样的Student类(可以不用加[JsonConstructor],Json.NET会自动匹配构造函数参数)

// 序列化到文件
var student = new Student(
    "1234567890123",
    "Maria Popescu",
    12345,
    new DateTime(2021, 9, 1),
    0,
    new int[] { 9, 10, 8 });

string json = JsonConvert.SerializeObject(student, Formatting.Indented);
File.WriteAllText("student.json", json);

// 从文件读取
string jsonFromFile = File.ReadAllText("student.json");
Student loadedStudent = JsonConvert.DeserializeObject<Student>(jsonFromFile);

Json.NET默认会处理私有字段(可以通过配置调整),并且能自动匹配构造函数参数,处理readonly字段也很顺畅。

方案3:二进制序列化(适合.NET Framework,性能高但不跨平台)

如果需要高效的二进制格式,可以用.NET的二进制序列化:

首先给Student类和基类加上[Serializable]特性:

[Serializable]
public class Person
{
    public string Cnp { get; }
    public string Nume { get; }

    public Person(string cnp, string nume)
    {
        Cnp = cnp;
        Nume = nume;
    }
}

[Serializable]
public class Student : Person
{
    private int[] note;//分数向量
    private DateTime dataInrolarii;
    private int nrRestante;
    private readonly int nrMatricol;
    private const string sex = "feminin";
    public static int anStudiu = 3;

    public Student(string cnp, string nume, int nrMatricol, DateTime dataInrolarii, int nrRestante, int[] note) 
        : base(cnp, nume)
    {
        this.nrMatricol = nrMatricol;
        this.dataInrolarii = dataInrolarii;
        this.nrRestante = nrRestante;
        this.note = note ?? Array.Empty<int>();
    }
}

然后序列化和读取代码:

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

// 序列化到文件
var student = new Student(
    "1234567890123",
    "Maria Popescu",
    12345,
    new DateTime(2021, 9, 1),
    0,
    new int[] { 9, 10, 8 });

BinaryFormatter formatter = new BinaryFormatter();
using (FileStream stream = new FileStream("student.bin", FileMode.Create))
{
    formatter.Serialize(stream, student);
}

// 从文件读取
using (FileStream stream = new FileStream("student.bin", FileMode.Open))
{
    Student loadedStudent = (Student)formatter.Deserialize(stream);
}

注意:二进制序列化不跨平台(比如.NET Core读取.NET Framework序列化的文件可能有问题),而且static成员和const不会被序列化。

方案4:自定义文本格式解析(比如CSV)

如果你的文件是自定义的文本格式(比如每行是学生数据,分数用逗号分隔),可以自己写解析逻辑:

假设文件内容格式如下:

CNP,Nume,NrMatricol,DataInrolarii,NrRestante,Note
1234567890123,Maria Popescu,12345,2021-09-01,0,9,10,8

解析代码:

using System.IO;
using System.Linq;

// 读取文件并解析
string[] lines = File.ReadAllLines("students.csv");
List<Student> students = new List<Student>();

// 跳过表头
for (int i = 1; i < lines.Length; i++)
{
    string[] parts = lines[i].Split(',');
    if (parts.Length < 6) continue;

    string cnp = parts[0];
    string nume = parts[1];
    int nrMatricol = int.Parse(parts[2]);
    DateTime dataInrolarii = DateTime.Parse(parts[3]);
    int nrRestante = int.Parse(parts[4]);
    int[] note = parts.Skip(5).Select(int.Parse).ToArray();

    Student student = new Student(cnp, nume, nrMatricol, dataInrolarii, nrRestante, note);
    students.Add(student);
}

// 使用解析后的学生对象
foreach (var s in students)
{
    Console.WriteLine($"{s.Nume} 的分数:{string.Join(", ", s.Note)}");
}

这种方式适合需要手动控制格式的场景,但需要自己处理异常(比如格式错误、类型转换失败)。

关键注意事项

  • readonly字段:反序列化时需要确保构造函数能接收该字段的值,或者序列化器支持直接赋值(比如Json.NET和System.Text.Json在配置正确时可以处理)。
  • 静态/const成员:这些属于类级别的数据,不属于实例,序列化器默认不会处理它们。如果需要保存静态状态,要手动读取和写入。
  • 异常处理:实际代码中要添加try-catch块,处理文件不存在、格式错误、类型转换失败等异常。
  • 基类序列化:确保Student的基类(Person)也支持序列化,否则会丢失基类的属性数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:44:04