c# . net:反序列化json树



晚上好

对于我的特定问题,我必须创建一个菜单(更准确地说是一个菜单树)。因此,我决定使用具有以下结构的复合设计模式:

  • IMenuComponent(一个定义一些属性等的接口)
  • 菜单(包含IMenuComponent的列表)
  • MenuEntry (a leaf)

所以,我必须在知道回去的路的同时浏览它。最明显的答案是有一个'parent'属性。

我有以下json树:

{
  "Guid": "08967257-9306-4717-a76a-e1a4f0050505",
  "Parent": null,
  "Title": "Main Menu",
  "Message": "A sample message",
  "Elements": [
    {
      "$type": "Menu",
      "Guid": "26dfca59-9163-4b11-8033-e8ad13f3f5cc",
      "Parent": "08967257-9306-4717-a76a-e1a4f0050505",
      "Title": "Option 1",
      "Message": "Another sample message",
      "Elements": [
        {
          "$type": "MenuEntry",
          "Parent": "26dfca59-9163-4b11-8033-e8ad13f3f5cc",
          "Title": "Entry 1",
          "Message": "Another sample message"
        },
        {
          "$type": "MenuEntry",
          "Parent": "26dfca59-9163-4b11-8033-e8ad13f3f5cc",
          "Title": "Entry 2",
          "Message": "Another sample message"
        },
        {
          "$type": "MenuEntry",
          "Parent": "26dfca59-9163-4b11-8033-e8ad13f3f5cc",
          "Title": "Entry 3",
          "Message": "Another sample message"
        }
      ]
    },
    {
      "$type": "MenuEntry",
      "Parent": "08967257-9306-4717-a76a-e1a4f0050505",
      "Title": "Option 2",
      "Message": "Another sample message"
    }
  ]
}

这与反序列化本身无关,因为它应该工作。

我的问题是,在将文件反序列化到"菜单"(根)后,我必须访问父母。我能想到两种方法:

  • 在运行时使用它的Guid查找'父' -根据树的大小可能会导致性能不佳;
  • 添加一个'Menu'属性到'Menu'和'MenuEntry'类来存储'parent'并填充它,在从json反序列化后找到相应的Guid。基本上,我将在应用程序启动时立即将其放在一起,以防止在运行时查找。这也可能是糟糕的性能方面。

怎么走?我该怎么做呢?

作为旁注,我使用Newtonsoft.Json

谢谢你的帮助!

@Ian Mercer的评论实际上帮助我找到了一个简单的解决方案(使用我上面帖子中描述的第二种方法)。

第二种方法并不真正依赖于Guids。在反序列化之后,我可以迭代每个菜单集合(无论如何我都可能会这样做)并直接将引用提供给'父'。

private void ConnectTree(Menu menu)
{
    foreach (IMenuComponent component in menu.Elements) {
        if (component is Menu) {
            (component as Menu).ParentMenu = menu;
            ConnectTree (component as Menu);
        } 
        else if (component is MenuEntry) {
            (component as MenuEntry).ParentMenu = menu;
        }
    }
}

只需调用ConnectTree(_deserializedMenu)

编辑:

@Brian Rogers刚刚提到了json net中的PreserveReferencesHandling属性。最初的问题都是关于json不支持循环引用,但这解决了它-它是相同的逻辑使用Guids。有多种解决方案,知道这些总是好的。

谢谢!

相关内容

  • 没有找到相关文章

最新更新