使用列表返回对象而不是数组的JSON对象的差异

时间:2017-08-24 11:16:26

标签: c# json

我正在尝试通过将两个C#对象转换为JSON然后进行差异来比较它们。它适用于所有原语但我不明白为什么当我更改列表中的项目时,比较是重新调整对象而不是数组。

我将列出3个案例,前两个案例按预期进行:

案例1 - 上一个列表为空,稍后添加了一个项目

scrollPadding: false

结果符合预期*

var company = new Company(15)
{
    Name = "Sega"
};
var previousCat = new Category(1)
{
    Name = "Cat X",
    Department = new Department(100)
    {
        Name = "Department 100",
        Company = company
    },
    Companies = new List<Company>()
};
var currentCat = new Category(1)
{
    Name = "Cat XYZ",
    Department = new Department(100)
    {
        Name = "Department 100",
        Company = company
    },
    Companies = new List<Company> { company }
};

案例2 - 上一个列表中有一个项目稍后被删除

// New Value:

[
  {
    "Name": "Sega",
    "Categories": null,
    "Id": 15
  }
]

// Old value:

[]

结果符合预期*

var company = new Company(15)
{
    Name = "Sega"
};
var previousCat = new Category(1)
{
    Name = "Cat X",
    Department = new Department(100)
    {
        Name = "Department 100",
        Company = company
    },
    Companies = new List<Company>
    {
        company
    }
};
var currentCat = new Category(1)
{
    Name = "Cat XYZ",
    Department = new Department(100)
    {
        Name = "Department 100",
        Company = company
    },
    Companies = new List<Company>()
};

案例3 - 两个列表都有项目

// New value:

[]

// Old Value:

[
  {
    "Name": "Sega",
    "Categories": null,
    "Id": 15
  }
]

结果不符合预期*

var sega = new Company(15)
{
    Name = "Sega"
};
var sony = new Company(30)
{
    Name = "Sony"
};
var nintendo = new Company(45)
{
    Name = "Nintendo"
};
var microsoft = new Company(60)
{
    Name = "Microsoft"
};
var previousCat = new Category(1)
{
    Name = "Cat X",
    Department = new Department(100)
    {
        Name = "Department 100",
        Company = sega
    },
    Companies = new List<Company>
    {
        sega,
        nintendo
    }
};
var currentCat = new Category(1)
{
    Name = "Cat XYZ",
    Department = new Department(100)
    {
        Name = "Department 100",
        Company = sega
    },
    Companies = new List<Company>
    {
        nintendo,
        sony,
        microsoft
    }
};

如您所见,第三个结果返回一个对象,而不是一个数组。那是为什么?

我正在使用这个课程:

https://github.com/khalidsalomao/SimpleHelpers.Net/blob/master/SimpleHelpers/ObjectDiffPatch.cs

这样:

// New value: { "0": { "Name": "Nintendo", "Id": 45 }, "1": { "Name": "Sony", "Id": 30 }, "2": { "Name": "Microsoft", "Categories": null, "Id": 60 }, "@@ Count": 3 } // Old value: { "0": { "Name": "Sega", "Id": 15 }, "1": { "Name": "Nintendo", "Id": 45 }, "@@ Count": 2 }

1 个答案:

答案 0 :(得分:1)

这可能是因为您链接的代码(ObjectDiffPatch)构建数组diff对象的方式。这是相关部分,正如我recreated it in LINQPad

screenshot from LinqPad

我将此作为图片添加,因为此工具提示非常重要。但是让我们从顶部开始:

如果其中一个数组为空,则它会正确保留原始结构:抓取两个数组(其中一个为空),并将其添加到字段名称“Companies”下。

但是,如果两者都不是空的,那么它开始逐个比较它们的内容。当找到差异时,代码会使用AddNewValuesToken将其添加到diff对象,这需要字段名称作为其第三个参数但是这里我们没有字段名称,只是一个数组索引

现在,代码通过将数组索引转换为string并将其视为字段名称来“解决”此问题。难怪生成的JObject也会这样对待它 - 这就是为什么你在输出中看到一个对象,它曾经是数组索引,成为字段。