读取JSON文件会将项目添加到同一类的另一个属性的列表中

时间:2019-04-23 07:19:47

标签: c# json

我有一组类似以下的类:

public class Class1 : IClass
{
    public List<Class2> Class2List { get { return Class3Instance.Class2List; } }

    public Class3 Class3Instance { get; set; }
}

public class Class2
{
    public string Field1 { get; set; }
    public int Field2 { get; set;}
}

public class Class3
{
    public List<Class2> Class2List { get; set; }
}

我正在存储有关Class1列表的信息,并且该列表的序列化工作符合预期,即生成的文件包含了我对其进行序列化的所有信息。

当我反序列化时,虽然没有给出异常并且我可以阅读信息,但是还是有一个问题,这是在Class3中添加了额外的信息。

Class3是一个类,在我的应用程序中将其用作终身使用的Class3实例的列表,我还使用它来查询应用程序流中与该问题无关的其他字段的信息。

问题是,当我在Class2List中读取包含1个或多个项目的Class1列表时,我看到这些项目正在添加到与Class1相关的Class3的Class2List属性中。

如果Class1列表中的多个元素引用同一Class3实例,则所有Class2List成员都将添加到引用的Class3中。

我不知道为什么会这样,这是我做错了的事情,但是我发现将字段Class2List标记为JsonIgnore可以解决此问题,并且我看不到将Class1.Class2List添加到实例中Class3.Class2List。

有人可以向我解释为什么我描述的行为实际上发生了吗?我不知道为什么这么做。

提供一个示例,使用最新版本的Newtonsoft.Json序列化以下代码的结果:

Class3 class3 = new Class3();
class3.Class2List2 = new List<Class2>();
class3.Class2List2.Add(new Class2() { Field1 = "Member1", Field2 = 1 });
class3.Class2List2.Add(new Class2() { Field1 = "Member2", Field2 = 2 });
class3.Class2List2.Add(new Class2() { Field1 = "Member3", Field2 = 3 });
class3.Class2List2.Add(new Class2() { Field1 = "Member4", Field2 = 4 });
class3.Class2List2.Add(new Class2() { Field1 = "Member5", Field2 = 5 });

Class1 class1 = new Class1();
class1.Class3Instance = class3;

给这个杰森:

{
  "Class3Instance": {
    "Class2List2": [
      {
        "Field1": "Member1",
        "Field2": 1
      },
      {
        "Field1": "Member2",
        "Field2": 2
      },
      {
        "Field1": "Member3",
        "Field2": 3
      },
      {
        "Field1": "Member4",
        "Field2": 4
      },
      {
        "Field1": "Member5",
        "Field2": 5
      }
    ]
  },
  "Class2List": [
    {
      "Field1": "Member1",
      "Field2": 1
    },
    {
      "Field1": "Member2",
      "Field2": 2
    },
    {
      "Field1": "Member3",
      "Field2": 3
    },
    {
      "Field1": "Member4",
      "Field2": 4
    },
    {
      "Field1": "Member5",
      "Field2": 5
    }
  ]
}

然后,如果我立即反序列化JSON并再次对其进行序列化,则会得到以下结果:

{
  "Class3Instance": {
    "Class2List2": [
      {
        "Field1": "Member1",
        "Field2": 1
      },
      {
        "Field1": "Member2",
        "Field2": 2
      },
      {
        "Field1": "Member3",
        "Field2": 3
      },
      {
        "Field1": "Member4",
        "Field2": 4
      },
      {
        "Field1": "Member5",
        "Field2": 5
      },
      {
        "Field1": "Member1",
        "Field2": 1
      },
      {
        "Field1": "Member2",
        "Field2": 2
      },
      {
        "Field1": "Member3",
        "Field2": 3
      },
      {
        "Field1": "Member4",
        "Field2": 4
      },
      {
        "Field1": "Member5",
        "Field2": 5
      }
    ]
  },
  "Class2List": [
    {
      "Field1": "Member1",
      "Field2": 1
    },
    {
      "Field1": "Member2",
      "Field2": 2
    },
    {
      "Field1": "Member3",
      "Field2": 3
    },
    {
      "Field1": "Member4",
      "Field2": 4
    },
    {
      "Field1": "Member5",
      "Field2": 5
    },
    {
      "Field1": "Member1",
      "Field2": 1
    },
    {
      "Field1": "Member2",
      "Field2": 2
    },
    {
      "Field1": "Member3",
      "Field2": 3
    },
    {
      "Field1": "Member4",
      "Field2": 4
    },
    {
      "Field1": "Member5",
      "Field2": 5
    }
  ]
}

如您所见,当我反序列化JSON时,Class2List成员已被复制。

1 个答案:

答案 0 :(得分:2)

如@mortb所说:

问题出在Class3Instance.Class2List的快捷方式中,除了先前在同一JSON文件中具有的引用成员之外,所有已在JSON中序列化的List成员都将添加到该快捷方式的引用中。

发生这种情况是因为反序列化不知道如何区分Class1中的快捷引用Class3Instance.Class2List和Class3中的Class2List,因此它不知道是否应该忽略快捷方式字段上的序列化或反序列化操作。

为了解决此问题,可以通过合同解析器或将属性[JsonIgnore]设置为快捷方式引用来解决此问题。