2014-01-13 93 views
2

我試圖序列化一個Dictionary<string, object>類型的字典來存儲一系列參數。該字典包含原始和複雜變量類型(如列表)。序列化按預期工作,但是當將JSON字符串反序列化回Dictionary<string, object>時,那些類型爲List<T>的參數將轉換爲Dictionary<string, object>類型。當我嘗試輸入這些參數時,我得到一個InvalidCastException用JsonFX反序列化字典

using UnityEngine; 
using System.Collections; 
using System.Collections.Generic; 
using JsonFx.Json; 

public class LevelBuilderStub : MonoBehaviour 
{ 
    class Person 
    { 
     public string name; 
     public string surname; 
    } 

    // Use this for initialization 
    void Start() 
    { 
     Dictionary<string, object> parameters = new Dictionary<string, object>(); 
     List<Person> persons = new List<Person>(); 
     persons.Add(new Person() { name = "Clayton", surname = "Curmi" }); 
     persons.Add(new Person() { name = "Karen", surname = "Attard" }); 

     parameters.Add("parameterOne", 3f); 
     parameters.Add("parameterTwo", "Parameter string info"); 
     parameters.Add("parameterThree", persons.ToArray()); 

     string json = JsonWriter.Serialize(parameters); 
     AVDebug.Log(json); 

     parameters = null; 
     parameters = JsonReader.Deserialize(json, typeof(Dictionary<string, object>)) as Dictionary<string, object>; 

     foreach(KeyValuePair<string, object> kvp in parameters) 
     { 
      string key = kvp.Key; 
      object val = kvp.Value; 
      AVDebug.Log(string.Format("Key : {0}, Value : {1}, Type : {2}", key, val, val.GetType())); 
     } 
    } 
} 

這將返回以下內容;

{"parameterOne":3,"parameterTwo":"Parameter string info","parameterThree":[{"name":"Clayton","surname":"Curmi"},{"name":"Karen","surname":"Attard"}]} 
Key : parameterOne, Value : 3, Type : System.Int32 
Key : parameterTwo, Value : Parameter string info, Type : System.String 
Key : parameterThree, Value : System.Collections.Generic.Dictionary`2[System.String,System.Object][], Type : System.Collections.Generic.Dictionary`2[System.String,System.Object][] 

的問題是,我怎樣才能得到一個List<Person>的參數鍵「parameterThree」。請注意,參數字典的內容將根據其上下文而有所不同。

+0

許多序列化庫處理或無法處理多態性。 [某些JsonFx版本可以支持類型提示](http://stackoverflow.com/questions/16904675/how-to-deserialize-polymorphic-collections-in-jsonfx);特別是[TowerOfBricks的這個版本越來越受到U3D的歡迎](https://bitbucket.org/TowerOfBricks/jsonfx-for-unity3d/src/bd8f83a8c1e5e841349399033d1709cc8378df2d/JsonFx/JsonFx.Json/bin/Release/)。 – rutter

回答

2

找到解決方案!必須使用JsonName屬性標記要序列化的類,然後使用writer/reader設置將變量的程序集名稱包含在JSON輸出中。以前面的例子,這是你必須做的;

using UnityEngine; 
using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Text; 
using JsonFx.Json; 

[Serializable] 
[JsonName("Person")] 
public class Person 
{ 
    public string name; 
    public string surname; 
} 

[JsonName("Animal")] 
public class Animal 
{ 
    public string name; 
    public string species; 
} 

[Serializable] 
public class Parameters 
{ 
    public float floatValue; 
    public string stringValue; 
    public List<Person> listValue; 
} 

public class SerializationTest : MonoBehaviour 
{ 
    // Use this for initialization 
    void Start() 
    { 
     ScenarioOne(); 
    } 

    void ScenarioOne() 
    { 
     Dictionary<string, object> parameters = new Dictionary<string, object>(); 
     List<Person> persons = new List<Person>(); 
     persons.Add(new Person() { name = "Clayton", surname = "Curmi" }); 
     persons.Add(new Person() { name = "Karen", surname = "Attard" }); 

     List<Animal> animals = new List<Animal>(); 
     animals.Add(new Animal() { name = "Chimpanzee", species = "Pan troglodytes" }); 
     animals.Add(new Animal() { name = "Cat", species = "Felis catus" }); 

     parameters.Add("floatValue", 3f); 
     parameters.Add("stringValue", "Parameter string info"); 
     parameters.Add("persons", persons.ToArray()); 
     parameters.Add("animals", animals.ToArray()); 

     // ---- SERIALIZATION ---- 

     JsonWriterSettings writerSettings = new JsonWriterSettings(); 
     writerSettings.TypeHintName = "__type"; 

     StringBuilder json = new StringBuilder(); 
     JsonWriter writer = new JsonWriter(json, writerSettings); 
     writer.Write(parameters); 

     AVDebug.Log(json.ToString()); 

     // ---- DESERIALIZATION ---- 

     JsonReaderSettings readerSettings = new JsonReaderSettings(); 
     readerSettings.TypeHintName = "__type"; 

     JsonReader reader = new JsonReader(json.ToString(), readerSettings); 

     parameters = null; 
     parameters = (Dictionary<string, object>)reader.Deserialize(); 

     foreach (KeyValuePair<string, object> kvp in parameters) 
     { 
      string key = kvp.Key; 
      object val = kvp.Value; 
      AVDebug.Log(val == null); 
      AVDebug.Log(string.Format("Key : {0}, Value : {1}, Type : {2}", key, val, val.GetType())); 
     } 
    } 
} 
+0

保存我的一天!這是否適用於Unity上的iOS? –