2017-09-19 2 views
0

Ich habe eine Klasse:C# Unity: JsonUtility Serialisierung verschachtelten mixed var

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; 
    } 
} 

Und in einem Ort an dem Code, den ich anrufen:

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

Nach dieser Operation, ich habe keine Daten Eigenschaft im Ergebnis JSON. Das Ergebnis ist: {"cmd":"chat/say","seedId":"","peerId":""}

Was ist los? Warum Daten in der endgültigen JSON-Struktur nicht angezeigt werden.

data hat beliebig Typ. (Möglicher String, benutzerdefiniertes Objekt, Schwimmer, array, etc ...)

EDIT: Ich interessiere mich für einige Umgehungslösung für meine Daten mit Serialisierung und Deserialisierung weil JsonUtility nicht alle primitiven Datentypen unterstützen Root für Daten und nur zum Parsen UnityEngine.Object Objekt benötigen.

+0

versuchen Sie Ihre Daten stattdessen als Zeichenfolge. konvertieren in Byte-Array und dann in String – Everts

+0

konvertieren, aber wie 'deserityize' byte [] 'Datentyp? Wenn es sein könnte, bitte Snippet mit Ihrer Antwort – featureoffuture

+0

meine schlechte Ich habe den Kommentar bearbeitet. Es sollte String sein. – Everts

Antwort

1

So JSONUtility unterstützt Objektserialisierung nicht. Sinnvoll, wenn Sie meinen, dass eine Objekttypreferenz nur eine 4-Byte-Adresse ohne Kenntnis der tatsächlichen Größe des Objekts ist. Der Serializer kann also nicht wissen, welche Daten zu serialisieren sind.

Sie können Ihr Byte [] in einen String64 umwandeln. Diese Zeichenfolge kann von der JsonUtility serialisiert werden. Hier ist, wie Sie Ihre Klasse aussehen:

[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; 
    } 
} 

Hier ist, wie Sie die Klasse ctor verwenden, jede Art unter Berücksichtigung können die Daten sein, Sie diese Methode verwenden können (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); 
} 

Jetzt sagen wir, Sie

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

Jetzt Sie abrufen möchten es einen Schwimmer Wert 5.12f haben:

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

Der Rückgabewert ist vom Typ Objekt. Wenn Sie den Typ wissen müssen (da Sie sagte, dass es irgendeine Art sein kann, können Sie wollen wissen, was es vor der Serialisierung war), nur verwenden:

f.GetType(); 

dies wird Ihnen sagen, was es tatsächlich ist. Es gibt keine direkte Möglichkeit, eine Typreferenz zu verwenden. Du müsstest durch Reflexion oder Dynamik gehen.

C# ist eine stark typisierte Sprache (im Gegensatz zu Sprachen wie Javascript oder PHP, wo man irgendwie den Typ einer Variablen wechseln kann). Aus diesem Grund, wenn Sie wie in Ihrer Situation enden, wo ein beliebiger Typ willkommen ist, ist dies kein gutes Design und wird zu Problemen oder einem riesigen Code führen, der schwer zu pflegen ist. Sie sollten die Möglichkeiten wahrscheinlich einschränken.

+0

Aber ich habe Node.js auf dem Backend und es sollte auch diese serialisierte Base64-String lesen. Ich schätze, es wird nicht funktionieren ... – featureoffuture