【问题标题】:How to change just last JSON item如何仅更改最后一个 JSON 项目
【发布时间】:2018-01-03 00:32:47
【问题描述】:

我正在构建一个用于修改现有 json 文件的应用程序。我已经制作了与我的 json 代码对应的所有类。大多数时候我需要复制整个 json 集合,然后只更改一些内容(如 id、索引等)。

我成功复制并添加了整个集合,当我尝试更改该集合中的某些内容时,它会更改我从中进行复制的集合。你能告诉我我做错了什么吗?

private void addFlightButton_Click(object sender, RoutedEventArgs e) {
  var originDestinationGroup = jsonObject.search.originDestinationGroup;
  OriginDestinationGroup oDGitem = originDestinationGroup.Last();
  var departureDateGroup = oDGitem.departureDateGroup;
  DepartureDateGroup dDGitem = departureDateGroup.Last();
  var originDestinationOptionRef = dDGitem.originDestinationOptionRef;
  OriginDestinationOptionRef oDORitem = originDestinationOptionRef.Last();

  originDestinationOptionRef.Add(oDORitem);
  char uriNumber = oDORitem.uri[oDORitem.uri.Length - 1];
  string uriString = oDORitem.uri.TrimEnd(oDORitem.uri[oDORitem.uri.Length - 1]);
  int idNumber = Convert.ToInt32(oDORitem.id);
  int indexNumber = oDORitem.index;

  uriNumber++;
  idNumber++;
  indexNumber++;

  OriginDestinationOptionRef oDORitemModify = originDestinationOptionRef.Last();
  oDORitemModify.uri = uriString + uriNumber.ToString();
  oDORitemModify.id = idNumber.ToString();
  oDORitemModify.index = indexNumber;
}

json 响应 - 未修改:

"search": {
  "originDestinationGroup": [{
        "departureDateGroup": [{
              "originDestinationOptionRef": [{
                  "uri": "option/1",
                  "id": "1",
                  "index": 0
                },
                {
                  "uri": "option/2",
                  "id": "2",
                  "index": 1
                }
              ]

json 响应 - 由我的代码修改:

"search": {
  "originDestinationGroup": [{
        "departureDateGroup": [{
              "originDestinationOptionRef": [{
                  "uri": "option/1",
                  "id": "1",
                  "index": 0
                },
                {
                  "uri": "option/3",
                  "id": "3",
                  "index": 2
                },
                {
                  "uri": "option/3",
                  "id": "3",
                  "index": 2
                }
              ]

json 响应 - 应该如何修改:

"search": {
  "originDestinationGroup": [{
        "departureDateGroup": [{
              "originDestinationOptionRef": [{
                  "uri": "/option/1",
                  "id": "1",
                  "index": 0
                },
                {
                  "uri": "option/2",
                  "id": "2",
                  "index": 1
                },
                {
                  "uri": "option/3",
                  "id": "3",
                  "index": 2
                }
              ]

类:

public class Search {
  public List<OriginDestinationGroup> originDestinationGroup { get; set; }
}
public class OriginDestinationGroup {
  public List<DepartureDateGroup> departureDateGroup { get; set; }
}
public class DepartureDateGroup {
  public List<OriginDestinationOptionRef> originDestinationOptionRef { get; set; }
}

public class OriginDestinationOptionRef {
  public string uri { get; set; }
  public string id { get; set; }
  public int index { get; set; }
}

提前谢谢你。

【问题讨论】:

  • 你能做一些更简单的 JSON 吗?它应该是什么,以及它实际上做什么?有了所有额外的数字/字母,我无法轻易分辨出它们之间的区别。
  • “当我尝试更改该集合中的某些内容时,它会更改我进行复制的集合” - 可能是因为您正在更改实际参考集合内。制作原件的副本 - 就像在集合上调用 ToList() 一样简单 - 并更改副本。
  • @gilliduck 我改变了它。这对你更好吗?
  • @stuartd 您能否参考代码的实际部分,我正在更改集合中的实际引用。谢谢
  • @Adicili 现在您已经根据下面的答案简化了代码!

标签: c# json


【解决方案1】:

所以,您将拿走该系列的最后一项:

OriginDestinationOptionRef oDORitem = originDestinationOptionRef.Last();

并将其添加到同一个集合中:

originDestinationOptionRef.Add(oDORitem);

所以集合现在包含 两个 指向同一个对象的指针。然后您获取集合中的最后一个对象并对其进行修改,但是由于您复制了引用而不是创建新对象,因此新条目和您复制的条目都会更改。 因此,您只需创建一个新的 OriginDestinationOptionRef 并将其添加到集合中,而不是复制现有的。

【讨论】:

  • 非常感谢,这个答案对我很有帮助。就一个问题。因为我的 json 比我放在这里的要复杂得多,所以我真的需要从最后一项复制所有内容,而不仅仅是进行一些更改。当我按您的方式添加 newItem 时,该新项目是空白的,我需要单独添加每个项目。那么如何复制再修改呢?
  • 您可以查看Object.MemberwiseClone 的文档,但请注意,这是一个“浅拷贝” - 所以它可以用于简单类型的属性,但如果您有引用 其他对象,您需要手动复制它们 - 但文档中有一个示例。
【解决方案2】:

这就是你出错的地方:

OriginDestinationOptionRef oDORitem = originDestinationOptionRef.Last();
originDestinationOptionRef.Add(oDORitem);

此代码从列表中获取最后一项,然后将对该同一个对象的新引用添加到同一个列表中。因此列表变长了 1 个条目,但最后两个条目现在指向内存中的同一个对象(原始对象,然后您继续更改)。

要解决这个问题,创建一个新的OriginDestinationOptionRef 对象:

var newItem = new OriginDestinationOptionRef();
originDestinationOptionRef.Add(newItem);

然后使用你现有的逻辑来设置newItem的属性。

【讨论】:

  • 非常感谢,这个答案对我很有帮助。就一个问题。因为我的 json 比我放在这里的要复杂得多,所以我真的需要从最后一项中复制所有内容,而不仅仅是进行一些更改。当我按您的方式添加 newItem 时,该新项目是空白的,我需要单独添加每个项目。那么如何复制再修改呢?
  • 无法以一种或另一种方式将所有属性从源复制到目标。参见例如此处:stackoverflow.com/q/930433/1220550 获取有关一些可能的方法的指导,这些方法可能在更多场景中有用,而不仅仅是这个。
猜你喜欢
  • 2015-03-07
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 1970-01-01
  • 2020-09-17
  • 2016-10-27
  • 2015-11-06
  • 2022-01-16
相关资源
最近更新 更多