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

本文关键字:列表 一个 反序列化 对象 NET Json 种类 类型 使用 | 更新日期: 2023-09-27 18:12:18

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

例如,我可以这样做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.
        }
    }

正如你所看到的,它只接受一种"武器"的格式(容器类的功能与上面所示的Item类相同)。我怎么能使它不同的构造器使用取决于在JSON文件中的武器?

我不能使用LitJSON的原因是,它不是一个可移植的库,这是一个要求与二元性(c#游戏引擎)使用的所有库。

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

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

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