【问题标题】:C# Unity: JsonUtility serialize nested mixed varC# Unity:JsonUtility 序列化嵌套混合变量
【发布时间】:2017-09-19 14:37:57
【问题描述】:

我有一堂课:

using System;

[Serializable]
public class GameMessage
{
    public string cmd;
    public object data;
    public string seedId;
    public string peerId;

    public GameMessage( string cmd, object data, string seedId = null, string peerId = null )
    {
        this.cmd = cmd;
        this.data = data;
        this.seedId = seedId;
        this.peerId = peerId;
    }
}

在我调用的代码的某个地方:

JsonUtility.ToJson(new GameMessage("chat/say", "hello!"));

执行此操作后,结果 JSON 中没有数据属性。 结果是:{"cmd":"chat/say","seedId":"","peerId":""}

怎么了?为什么数据没有出现在最终的 JSON 结构中。

data 具有 any 类型。 (可能的字符串、自定义对象、浮点数、数组等...)

编辑:我正在为我的数据寻找一些带有序列化和反序列化的解决方案,因为JsonUtility 不支持所有原始数据类型作为数据的根,并且只需要解析@987654326 @对象。

【问题讨论】:

  • 尝试将您的数据作为字符串。转换为字节数组再转换为字符串
  • 但是如何反序列化byte [] 数据类型呢?如果可以,请提供 sn-p 您的答案
  • 糟糕,我编辑了评论。它应该是字符串。
  • 字符串不行,因为 JsonUtility 无法将字符串反序列化为数组,例如...我试过了
  • “数据有任何类型。(可能是字符串、自定义对象、浮点数、数组等)” ... JsonUtility 无法序列化/反序列化 @987654330 @ 类型。您必须给出该对象的类型。

标签: c# json unity3d


【解决方案1】:

所以 JSONUtility 不支持对象序列化。当您认为对象类型引用只是一个四字节地址而不知道对象的实际大小时,这是有道理的。所以序列化器无法知道要序列化的数据是什么。

您可以将字节 [] 转换为 string64。该字符串可以由 JsonUtility 序列化。 这是您的班级的外观:

[Serializable]
public class GameMessage
{
    public string cmd;
    public string data;
    public string seedId;
    public string peerId;
    public byte [] Data{ get { return Encoding.ASCII.GetBytes(this.data); } }

    public GameMessage( string cmd, byte[] data, string seedId = null, string peerId = null )
    {
        this.cmd = cmd;
        this.data = Convert.BaseToString64(data);
        this.seedId = seedId;
        this.peerId = peerId;
    }
}

这里是你如何使用类ctor,考虑到任何类型都可以是数据,你可以使用这个方法(Convert any object to a byte[]):

byte[] ObjectToByteArray(object obj)
byte[] ObjectToByteArray(object obj)
{
    if(obj == null)
        return null;
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}
object ByteArrayToObject(byte[] buffer)
{
    MemoryStream ms = new MemoryStream (buffer);
    BinaryFormatter bf = new BinaryFormatter ();
    return bf.Deserialize (ms);
}

现在假设你有一个值为 5.12f 的浮点数

float f = 5.12f;
GameMessage gm = new GameMessage("chat/say", ObjectToByteArray((object)f));
string json = JsonUtility.ToJson(gm);

现在你想检索它:

var gm = JsonUtility.FromJson<GameMessage> (json);
byte[] array = gm.Data;
object f = ByteArrayToObject (array);
Debug.Log (f);

返回项目是对象类型。如果你需要知道它的类型(因为你说它可以是任何类型,你可能想知道它在序列化之前是什么),只需使用:

f.GetType();

这会告诉你它实际上是什么。没有使用 Type 引用进行强制转换的直接方法。你必须经历反思或动态。

C# 是一种强类型语言(与 Javascript 或 Php 等语言相反,您可以通过某种方式切换变量的类型)。出于这个原因,当您最终遇到您的情况时,欢迎任何给定的类型,这不是好的设计,并且会导致问题或大量代码,难以维护。您可能应该限制可能性。

【讨论】:

  • 但是我在后端有 Node.js,它也应该读取那个序列化的 base64 字符串。我想它不会工作......
【解决方案2】:

使用 Unity Newtonsoft.Json 库解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    相关资源
    最近更新 更多