【发布时间】:2021-10-15 21:44:07
【问题描述】:
我需要将Computer类型的对象转换为json字符串并写入文件。
我面临的问题是,由于计算机为超出此问题范围的目的实现 IEnumerable 接口,序列化后生成的 json 包含我的自定义枚举器提供的那些数据,尽管我正在寻找对象的属性(例如常规类如何进行通常的序列化)。
这是它的行为方式vs我希望它的行为方式:
计算机类:
class Computer : IEnumerable
{
public string Identifier { get; set; }
public string TeamViewerID { get; set; }
public string TeamViewerPassword { get; set; }
// and other properties
public List<CPU> CPUs { get; set; }
public List<GPU> GPUs { get; set; }
public List<PSU> PSUs { get; set; }
// and other collection properties
// This Enumerator allows me to iterate thorugh Computer's collection properties
// CPUs, GPUs, PSUs etc. as PropertyInfo
public IEnumerator GetEnumerator()
{
return new DeviceCollectionPropertyEnumerator();
}
}
序列化
// computerInstance is of type Computer (duh)
string json = Newtonsoft.Json.JsonConvert.SerializeObject(computerInstance);
这是我得到的 json
[
{
"Name": "GPUs",
"AssemblyName": "SystemInfoCollector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "SystemInfoCollector.Models.Computer",
"Signature": "System.Collections.Generic.List`1[SystemInfoCollector.Models.GPU] GPUs",
"Signature2": "System.Collections.Generic.List`1[[SystemInfoCollector.Models.GPU, SystemInfoCollector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] GPUs",
"MemberType": 16,
"GenericArguments": null
},
{
"Name": "PSUs",
"AssemblyName": "SystemInfoCollector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "SystemInfoCollector.Models.Computer",
"Signature": "System.Collections.Generic.List`1[SystemInfoCollector.Models.PSU] PSUs",
"Signature2": "System.Collections.Generic.List`1[[SystemInfoCollector.Models.PSU, SystemInfoCollector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] PSUs",
"MemberType": 16,
"GenericArguments": null
},
// And the rest of collection properties of Computer type ...
// This is the stuff that is provided by DeviceCollectionPropertyEnumerator
]
我希望看到的 json(如果我摆脱 IEnumerable 实现,我可以得到它)
{
"Identifier": "213231",
"TeamViewerID": null,
"TeamViewerPassword": null,
...
"CPUs": [],
"GPUs": [],
"PSUs": [],
...
}
我猜我的自定义枚举器会覆盖序列化时从计算机实例中获取属性的行为。如何克服这一点?如何像任何其他不实现IEnumerator 的常规类一样序列化这台计算机?
我使用 .NET Framework 4.7.2。
【问题讨论】:
-
那个
: IEnumerable使Computer 成为计算机列表,这很奇怪。你确定IEnumerable应该在那里吗?计算机有部件列表,但它本身并不是这些部件的列表 -
实现
IEnumerable会抛弃 JSON.NET - 尽量不要实现它。 -
我不建议您的
Computer实现IEnumerable,因为它不是一个集合。问问自己:“计算机是非通用集合吗?”,答案是否定的。如果您真的需要遍历PC的所有组件,我要做的是公开public IEnumerable<IPcComponent> Components并让您的各个组件实现IPcComponent -
不,等等。在迭代计算机组件时,我使用
IEnumerable应用迭代器设计模式,并且在我的代码库中有几个部分,我必须仅通过组件属性(组件 = cpus、gpus 等列表)和,为此,我创建了一个自定义枚举器,它允许我像这样迭代这些属性:foreach(PropertyInfo componentCollection in computer) { // do stuff },在这里实现 IEnumerable 并没有错,问题是序列化 :) -
嗯,说“一台计算机是并且永远是由包含组件的属性组成的
PropertyInfos 的集合”是不正确的。如果你真的非常需要PropertyInfo的列表,那么创建一个类似public IEnumerable<PropertyInfo> GetComponentProperties() { ... }的方法。因为现在,你告诉 JSON.Net 的是“这个类是一个集合,将我的内容(你通过foreaching 我得到的)序列化为 JSON 数组”,它正在执行和(正确地)序列化PropertyInfos
标签: c# json .net serialization json.net