首页 > 解决方案 > 是否有一个 XML 或 JSON 序列化器知道使用哪个构造函数来填充不可变对象并序列化 IEnumerable<> 属性?

问题描述

假设我有这个不可变的结构:

public struct LogGroup
{
    public Log<LowResolutionLogData> LowResolutionLog { get; }

    public IEnumerable<Log<MediumResolutionLogData>> MediumResolutionLogs { get; }

    public IEnumerable<Log<HighResolutionLogData>> HighResolutionLogs { get; }

    public LogGroup
    (
        Log<LowResolutionLogData> lowResolutionLog,
        IEnumerable<Log<MediumResolutionLogData>> mediumResolutionLogs,
        IEnumerable<Log<HighResolutionLogData>> highResolutionLogs
    )
    {
        LowResolutionLog = lowResolutionLog;
        MediumResolutionLogs = mediumResolutionLogs;
        HighResolutionLogs = highResolutionLogs;
    }
}

我如何序列化它而不必使IEnumerable<>属性成为某种具体类型(例如数组或列表)?

我如何反序列化它而不必使所有属性都可以设置(我希望它调用我创建的赋值构造函数)?

对象上的复杂类型也可能有自己的复杂类型和IEnumerable<>不可变属性。 Log<>虽然class它所采用的类型都是structs如此,因此使用赋值构造函数的反序列化需要同时适用于两者。其中一种类型具有大量属性,因此我想避免样板代码并尽可能动态处理序列化/反序列化。

标签: c#jsonxmlimmutability

解决方案


非常感谢 JSteward 为我指明了正确的方向。我所需要的只是序列化我的LogGroup并将其写入文件。

using (var streamWriter = File.CreateText(filePath))
    new JsonSerializer().Serialize(streamWriter, myLogGroup);

这是从文件中读取它并将其转换回LogGroup

using (var streamReader = File.OpenText(filePath))
    var myLogGroup = (LogGroup)new JsonSerializer().Deserialize(streamReader, typeof(LogGroup));

[JsonConstructor]为了使用它,我还必须标记每个结构的赋值构造函数Deserialize(否则属性会接收它们的默认值)。

所有类型抽象都被处理以进行序列化。

作为旁注,我使用 .tt 设计时模板来创建我的每个对象,以减少使用赋值构造函数的维护开销(我从一个源生成属性、构造函数参数和属性赋值)。


推荐阅读