当前位置: 首页 > 面试题库 >

重复序列化和反序列化会创建重复项

李弘光
2023-03-14
问题内容

大家好,我对json的实作性有疑问。我正在Unity下使用Json.NET包:我正在搜索一个数据库,该数据库可在我的应用程序上编辑,并通过wwwForm和php文件存储在服务器上。我毫不费力地创建它并将其推向网络。问题是,当我加载它时,数据库最后有一个新条目。数据库类是这样的:

public class Database   {
    public List<Army> armies { get; set;}

    public Database() {
        armies = new List<Army>();
        armies.Add (new Army());
    }
}

public class Army
{
    public string faction { get; set;}
    public List<Unit> army { get; set;}

    public Army()
    {
        faction = "RED";
        army = new List<Unit>();
        army.Add (new Unit());
    }
}

public class Unit
{
    public string name { get; set;}
    public float fissionTimer { get; set;}
    public float HP { get; set;}
    public int shield { get; set;}
    public float strenght { get; set;}
    public float movSpeed { get; set;}
    public float attackSpeed { get; set;}
    public float farmAggro { get; set;}
    public int criticPossibility { get; set;}
    public int armorPenetration { get; set;}
    public bool isContagious { get; set;}
    public int contagePossibility { get; set;}
    public string imgName {get;set;}

    public Unit()
    {
        name = "standard";
        fissionTimer = 8;
        HP = 100;
        shield = 0;
        strenght = 10;
        movSpeed = 5;
        attackSpeed = 0.1f;
        farmAggro = 0.1f;
        criticPossibility = 0;
        armorPenetration = 0;
        isContagious = false;
        contagePossibility = 0;
        imgName = "Red";
    }

    public Unit(string _name, float _fissionTimer, float _HP, int _shield, float _strenght, float _movSpeed, float _attackSpeed, 
                float _farmAggro, int _criticPossibility, int _armorPen, bool _iscontagious, int _contagePos, string _imgName)
    {
        name = _name;
        fissionTimer = _fissionTimer;
        HP = _HP;
        shield = _shield;
        strenght = _strenght;
        movSpeed = _movSpeed;
        attackSpeed = _attackSpeed;
        farmAggro = _farmAggro;
        criticPossibility = _criticPossibility;
        armorPenetration = _armorPen;
        isContagious = _iscontagious;
        contagePossibility = _contagePos;
        imgName = _imgName;
    }
}

要序列化和反序列化,我使用这两种方法:

IEnumerator LoadFile()
{
    WWW www = new WWW(dbPath);

    yield return www;

    var _database = JsonConvert.DeserializeObject<Database> (www.text);

    db = _database;
    SendMessage ("loaded", SendMessageOptions.DontRequireReceiver);
}

IEnumerator SaveFile(Database db)
{
    WWWForm form = new WWWForm();
    string serialized = JsonConvert.SerializeObject (db);
    form.AddField("theDatabase", serialized);

    WWW www = new WWW(phpPath, form);

    yield return www;

    if (www.error == null)
        Debug.Log ("saved" + serialized);
    else
        Debug.LogError ("error saving database");
}

使用默认构造函数(序列化和反序列化)的结果是:

{
    "armies": [
        {
            "faction": "RED",
            "army": [
                {
                    "name": "standard",
                    "fissionTimer": 8,
                    "HP": 100,
                    "shield": 0,
                    "strenght": 10,
                    "movSpeed": 5,
                    "attackSpeed": 0.1,
                    "farmAggro": 0.1,
                    "criticPossibility": 0,
                    "armorPenetration": 0,
                    "isContagious": false,
                    "contagePossibility": 0,
                    "imgName": "Red"
                }
            ]
        },
        {
            "faction": "RED",
            "army": [
                {
                    "name": "standard",
                    "fissionTimer": 8,
                    "HP": 100,
                    "shield": 0,
                    "strenght": 10,
                    "movSpeed": 5,
                    "attackSpeed": 0.1,
                    "farmAggro": 0.1,
                    "criticPossibility": 0,
                    "armorPenetration": 0,
                    "isContagious": false,
                    "contagePossibility": 0,
                    "imgName": "Red"
                }
            ]
        }
    ]
}

有2个军队和2个单位。我在哪里做错了?提前致谢


问题答案:

发生这种情况的原因是由于两件事的结合:

  1. 您的类构造函数会自动将默认项添加到其各自的列表中。Json.Net调用这些相同的构造函数在反序列化期间创建对象实例。
  2. Json.Net的默认行为是在反序列化期间重用(即添加到)现有列表,而不是替换它们。

要解决此问题,您可以更改代码,以使构造函数不会自动将默认项添加到列表中,或者可以配置Json.Net以在反序列化时替换列表,而不是重复使用它们。可以通过将ObjectCreationHandling设置更改Replace为如下所示来完成后者:

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.ObjectCreationHandling = ObjectCreationHandling.Replace;

var database = JsonConvert.DeserializeObject<Database>(www.text, settings);


 类似资料:
  • 如何用gson 2.2.4序列化和反序列化像这样的简单枚举?

  • 我在搞lambdas的Java序列化。 我有两个完全独立的项目,其中只有一个类。 项目1: 项目二: 但是,在尝试反序列化可运行文件时,它会抛出一个异常,说它找不到 ...我有什么办法可以避免这种情况吗?

  • 假设我有这样的json,我想将其反序列化为一个名为SubscriberProfile的对象。 当我使用以下代码时,它可以正常工作, 但如果json中缺少字段2,我希望objectmapper抛出和异常(可能缺少字段1和字段2)。 所以这样的json应该抛出一个异常 我曾尝试使用注释,但仅在序列化它时有效。 你知道我该怎么解决这个问题吗? 提前感谢

  • 问题内容: 我注意到存储在Redis中的某些序列化对象在反序列化方面遇到问题。 当我对Redis中存储的对象类进行更改时,通常会发生这种情况。 我想了解问题,以便为解决方案设计一个清晰的方案。 我的问题是,什么导致反序列化问题?移除公共/私人财产会引起问题吗?也许添加新属性?向类添加新功能会产生问题吗?那么更多的构造函数呢? 在我的序列化对象中,我有一个属性Map,如果我更改(更新了一些属性,添加

  • 问题内容: Golang中将结构序列化和反序列化为字符串的最佳方法(完整性和性能)是什么,反之亦然? 例如,如果我有这个结构: 我想将其存储在Redis上并取回。我试过保存,整型和字符串,这很好,但是如何存储结构对象? 问题答案: 使用gob和base64可以解决问题,例如: 当您需要序列化自定义结构或类型(例如struct)时,只需添加以下行:

  • 主要内容:1 Java序列化和反序列化,2 Java序列化的优点,3 java.io.Serializable接口,4 Java ObjectOutputStream,5 Java ObjectInputStream,6 Java序列化的例子,7 Java反序列化的例子1 Java序列化和反序列化 Java中的序列化是一种将对象状态写入字节流的机制。它主要用于Hibernate,RMI,JPA,EJB和JMS技术。 序列化的反向操作称为反序列化,其中字节流被转换为对象。序列化和反序列化过程与平台