【问题标题】:How to use json.net(JObject/Jarray/Jtoken) and convert to class in the fastest way into a dictionary?如何使用 json.net(JObject/Jarray/Jtoken) 并以最快的方式将类转换为字典?
【发布时间】:2015-12-15 01:14:06
【问题描述】:

如何使用 json.net(JObject/Jarray/Jtoken) 并以最快(性能)的方式将类转换为字典?字典的关键是在json文件中看到“名称”

有人可以帮忙吗?

非常感谢!

seed.json
       {
          "Seed": [
                {
                    "name": "Cheetone",
                    "growthrate": 1,
                    "cost": 500
                },
                {
                    "name": "Tortone",
                    "growthrate": 8,
                    "cost": 100
                }
            ],
        }


    public class SoilStat
    {
        public int growthRate;
        public int cost;
    }

    public class DataLoader : MonoSingleton<DataLoader>
    {
        public string txt;
        Dictionary<string, SoilStat> _soilList = new Dictionary<string, SoilStat>();

        JObject rawJson = JObject.Parse(txt);

        ???
    }

【问题讨论】:

  • 什么是_txtAsset?是顶部的那个 JSON 的 sn-p 吗?如果是这样,您能否提供您正在使用的实际有效 JSON? (事实上​​,它的格式不正确)
  • 您的问题听起来很笼统,但您显示的实际代码似乎并非如此。字典键应该是什么?
  • 更新了代码@dbc
  • “最快”是指“最高性能”还是“最直接”?
  • 那么我可以通过Eric Lippert 将您指向Which is faster?。我可以给你一个非常简单的方法来做你想做的事,但你需要自己做性能测试。想要吗?

标签: c# json c#-4.0 json.net


【解决方案1】:

一种简单的方法是使用SelectTokens 挑选出您感兴趣的 JSON 部分,然后反序列化这些位。因此:

        var rawJson = JObject.Parse(txt);
        var _soilList = rawJson.SelectTokens("Seed[*]").ToDictionary(t => t["name"], t => t.ToObject<SoilStat>());

更复杂的解决方案是创建 DTO objects 进行反序列化,然后将它们映射到您想要的类:

public class NamedSoilStat : SoilStat
{
    public string name { get; set; }
}

public class RootObject
{
    public RootObject() { this.Seed = new List<NamedSoilStat>(); }
    public List<NamedSoilStat> Seed { get; set; }
}

然后:

        var root = JsonConvert.DeserializeObject<RootObject>(txt);
        var _soilList = root.Seed.ToDictionary(t => t.name, t => new SoilStat { cost = t.cost, growthRate = t.growthRate });

至于哪个性能更高,您需要test for yourself

顺便说一句,如果您的 txt JSON 字符串来自文件并且很大,您应该考虑将其流式传输,而不是将其读入中间字符串。见Performance Tips: Optimize Memory Usage

【讨论】:

  • 由于对 unity5 的一些限制,我无法使用 selecttoken。有没有其他方法可以在不创建 DTO 对象的情况下做到这一点? @dbc
【解决方案2】:

根据我的经验,使用JsonConvert 比使用JObject.Parse() 快​​得多。请参阅this page for a performance comparison(在 Windows Phone 上,但我想它在桌面上会类似),该页面的链接是 an example that uses JsonConvert

【讨论】:

  • 谢谢,但我如何使用 JsonConvert.DeserializeObject 到以种子“名称”为键的字典中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
  • 1970-01-01
相关资源
最近更新 更多