是否有一个 XML 或 JSON 序列化器知道使用哪个构造函数来填充不可变对象并序列化 IEnumerable<> 属性? [关闭]
Posted
技术标签:
【中文标题】是否有一个 XML 或 JSON 序列化器知道使用哪个构造函数来填充不可变对象并序列化 IEnumerable<> 属性? [关闭]【英文标题】:Is there an XML or JSON Serializer that knows which Constructor to use to Populate an Immutable Object and also Serialize IEnumerable<> Properties? [closed] 【发布时间】:2021-02-16 08:02:23 【问题描述】:假设我有这个不可变的结构:
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<>
s 作为不可变属性。 Log<>
是 class
,而它采用的类型都是 structs
,因此使用赋值构造函数的反序列化需要对两者都有效。其中一种类型具有大量属性,因此我想避免样板代码并尽可能动态处理序列化/反序列化。
【问题讨论】:
我相信 Newtonsoft JSON 可以开箱即用地处理这个问题,只要构造函数参数名称与您应该可以使用的属性名称匹配。 很好,我只是尝试了 JSON.NET,但在获取读取/写入文件所需的正确对象时遇到了麻烦。你能举个简单的例子吗? 同意,Json.NET 可以使用非默认构造函数进行反序列化。有关选择构造函数的精确算法,请参见:How does JSON deserialization in C# work。但是,如果有 多个 参数化构造函数,则 Json.NET 没有内置方法可以知道使用哪个不存在标记一个[JsonConstructor]
。 IE。您的 LogGroup
应该可以很好地反序列化,但更复杂的不可变类型可能不会。
我刚刚尝试过 JSON.NET,但在获取读取/写入文件所需的正确对象时遇到了麻烦 -- 那么请分享minimal reproducible example。 Json.NET 当然可以从文件反序列化,参见newtonsoft.com/json/help/html/… 和newtonsoft.com/json/help/html/…
【参考方案1】:
非常感谢 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 设计时模板来创建我的每个对象,以减少使用赋值构造函数的维护开销(我从一个源生成属性、构造函数参数和属性赋值)。
【讨论】:
将文件加载到字符串中,然后从字符串中反序列化,当文件很大时可能会对性能产生负面影响。相反,您可以直接从流中反序列化,如 Performance Tips: Optimize Memory Usage、Deserialize JSON from a file 和 Serialize JSON to a file 所示。 代码已根据之前的评论更改。以上是关于是否有一个 XML 或 JSON 序列化器知道使用哪个构造函数来填充不可变对象并序列化 IEnumerable<> 属性? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
是否有任何引擎用于获取 twitter xml 或 json 输出? [关闭]