简体   繁体   English

用列表对JSON对象进行比较会返回对象而不是数组

[英]Making a diff of JSON objects with lists return object instead of array

I'm trying to compare two C# objects by converting them to JSON and then making a diff. 我试图通过将两个C#对象转换为JSON,然后进行比较来比较它们。 It works fine for all primitives but I don't understand why when I change items in a list that had items the comparison is retuning an object instead of an array. 它对所有原语都适用,但是我不明白为什么当我更改具有项目的列表中的项目时,比较会重新调整对象而不是数组。

I'm going to list 3 cases, the first 2 go by as expected: 我将列出3个案例,前2个案例按预期进行:

Case 1 - previous list was empty and one item was added later 情况1-先前的列表为空,后来添加了一项

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 }
};

Result as expected* 结果符合预期*

// New Value:

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

// Old value:

[]

Case 2 - previous list had one item that was later removed 情况2-先前的清单中有一项后来被删除

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>()
};

Result as expected* 结果符合预期*

// New value:

[]

// Old Value:

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

Case 3 - both lists have items 情况3-两个列表都有项目

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
    }
};

Result NOT as expected* 结果不符合预期*

// 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
}

As you can see the third result returns an object, not an array. 如您所见,第三个结果返回一个对象,而不是数组。 Why is that? 这是为什么?

I'm using this class: 我正在使用此类:

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

This way: 这条路:

var diff = ObjectDiffPatch.GenerateDiff(Previous,Current);

That's probably because of the way the code you linked ( ObjectDiffPatch ) builds up the array diff object. 这可能是因为您链接的代码( ObjectDiffPatch )构建数组diff对象的方式。 This is the relevant part, as I recreated it in LINQPad : 这是相关的部分,正如我在LINQPad中重新创建的那样

LinqPad的屏幕截图

I added this as an image because that tooltip is important here. 我将此图像添加为图片,因为该工具提示在这里很重要。 But let's start at the top: 但是,让我们从顶部开始:

If one of the arrays is empty, it properly keeps the original structure: grabs the two arrays (one of which is empty), and adds them under the field name "Companies". 如果其中一个数组为空,则将适当地保留原始结构:抓取两个数组(其中一个为空),并将其添加到字段名称“ Companies”下。

If, however, neither are empty, then it starts comparing their contents, piece by piece. 但是,如果两个都不为空,则开始逐个比较它们的内容。 And when a difference is found, the code adds it to the diff object using AddNewValuesToken , which expects a field name as its third parameter, but here we don't have a field name, just an array index . 当发现差异时,代码使用AddNewValuesToken将其添加到diff对象中,该对象期望将字段名作为其第三个参数, 但是这里我们没有字段名,只有数组索引

Now, the code "solves" this by converting the array index to string , and treating it as a field name. 现在,代码通过将数组索引转换为string并将其视为字段名称来“解决”此问题。 No wonder that the resulting JObject will treat it that way too – this is why you see an object in the output, where what used to be array indices, become fields. 难怪最终的JObject也将以这种方式对待它-这就是为什么您在输出中看到一个对象的原因,该对象原来是数组索引,成为字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM