如何像常规 class 一样序列化 IEnumerable?

How to serialize an IEnumerable like a regular class?

我需要将 Computer 类型的对象转换为 json 字符串并将其写入文件。

我面临的问题是,由于 Computer 实现 IEnumerable 接口的目的超出了这个问题的范围,序列化后的结果 json 包含这些片段由我的自定义枚举器提供的数据,尽管我正在寻找获取对象的属性(例如常规 classes 中通常的序列化是如何发生的)。

这是它的行为方式我希望它的行为方式:

计算机class:

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?

的常规 class 一样序列化此计算机

我使用 .NET Framework 4.7.2。

JsonObjectAttribute 附加到您的计算机类型:

[JsonObject]
class Computer : IEnumerable

这将强制序列化将其像对象而不是集合一样序列化,从而完全忽略 IEnumerableIEnumerable<T>

请注意,这将完全忽略 IEnumerable 部分,因此必须忽略通过该集合支持序列化的任何内容,或者如您所示通过这些属性进行处理。


正如对您问题的评论已经指出的那样,使计算机成为其组件的隐式集合似乎是一种奇怪的设计。既然你已经声明它是遗留代码,你希望不要打扰太多,只想修复 Json.net 序列化,你可以使用该属性来绕过自动集合序列化。