使用Json.NET将多种类型的对象反序列化为一个列表

时间:2016-10-08 05:23:02

标签: c# json list parsing 2d-games

我在使用Json.NET时遇到了麻烦,我从LitJSON转移到了Json.NET。它工作得很好,除了我不能分离不同类型的对象以强制它们使用不同的构造函数。

例如,我可以使用LitJSON执行此操作:

for (int i = 0; i < totalAmountOfItems; i++)
    {
        if (itemData[i]["type"].ToString() == "Weapons")
        {
            for (int j = 0; j < itemData[i]["array"].Count; j++)
            {
                database.Add(new Item((int)itemData[i]["array"][j]["id"], itemData[i]["array"][j]["title"].ToString(),
                                  itemData[i]["array"][j]["weaponType"].ToString(), (bool)itemData[i]["array"][j]["stackable"], itemData[i]["array"][j]["slug"].ToString(),
                                  (int)itemData[i]["array"][j]["damage"], (int)itemData[i]["array"][j]["durability"])); //Reads the component in quotes for object
                                                                                                                        //with address 'i'. Creates new item based
                                                                                                                        //on this data.
                                                                                                                        //Note: If using only one .Add method, all items in database must follow it's pattern.
            }
        }
        else if (itemData[i]["type"].ToString() == "Food")
        {
            for (int j = 0; j < itemData[i]["array"].Count; j++)
            {
                database.Add(new Item((int)itemData[i]["array"][j]["id"], itemData[i]["array"][j]["title"].ToString(),
                                  (bool)itemData[i]["array"][j]["stackable"], itemData[i]["array"][j]["slug"].ToString(),
                                  (int)itemData[i]["array"][j]["hungerAmount"]));
            }
        }
        else if (itemData[i]["type"].ToString() == "Medicine")
        {
            for (int j = 0; j < itemData[i]["array"].Count; j++)
            {
                database.Add(new Item((int)itemData[i]["array"][j]["id"], itemData[i]["array"][j]["title"].ToString(),
                                  (bool)itemData[i]["array"][j]["stackable"], itemData[i]["array"][j]["slug"].ToString(),
                                  (int)itemData[i]["array"][j]["healAmount"]));
            }
        }
        else if (itemData[i]["type"].ToString() == "Equippable")
        {
            for (int j = 0; j < itemData[i]["array"].Count; j++)
            {
                database.Add(new Item((int)itemData[i]["array"][j]["id"], itemData[i]["array"][j]["title"].ToString(),
                                  (bool)itemData[i]["array"][j]["stackable"], itemData[i]["array"][j]["slug"].ToString(),
                                  (int)itemData[i]["array"][j]["armorAmount"], (int)itemData[i]["array"][j]["insulationAmount"]));
            }
        }
        else if (itemData[i]["type"].ToString() == "Resource")
        {
            for (int j = 0; j < itemData[i]["array"].Count; j++)
            {
                database.Add(new Item((int)itemData[i]["array"][j]["id"], itemData[i]["array"][j]["title"].ToString(),
                                  (bool)itemData[i]["array"][j]["stackable"], itemData[i]["array"][j]["slug"].ToString()));
            }
        }
    }

这允许我使用一个容器类(Item)来使用不同的构造函数来存储各种不同对象的数据。我如何在Json.NET中做同样的事情?

以下是我目前使用的代码:

public void ConstructWeaponDatabase()
    {
        using (Stream s = FileOp.Open(@"Data\Misc\Weapons.json", FileAccessMode.Read)) //Opens file
        {
            using (StreamReader r = new StreamReader(s)) //Declares new reader
            {
                string json = r.ReadToEnd(); //Reads 'r' and its stream (s) to the end of the file.
                weaponDatabase = JsonConvert.DeserializeObject<List<Misc.Weapon>>(json); //Json.NET magic to place items from file
            }                                                                            //into list.
        }
    }

正如您所看到的,它只采用了一种格式的&#34;武器&#34; (容器类的功能与上面显示的Item类相同)。我如何根据JSON文件中的武器使用不同的构造函数?

我无法使用LitJSON的原因是它不是一个可移植的库,这是Duality(A C#游戏引擎)使用的所有库的要求。

1 个答案:

答案 0 :(得分:0)

您可以使用派生的JsonConverter并覆盖ReadJson方法来实现自定义逻辑,然后将此转换器的实例传递给Deserialize - 看一下{{3} }}

此外,您可能需要考虑使用Item作为基类,并使用派生类来表示不同的项目(FoodMedicine等),而不是使用单个项目用于表示概念上不同对象的类。