2015-03-25 95 views
2

使用折舊的System.Json,我得到了我期望的結果(來自Javascript): 孩子得到一個GrandChild和所有父母知道它...嵌套的JSON對象不更新/繼承使用Json.NET

var Parents   = new JsonObject(); 
var Children  = new JsonObject(); 

var Parent   = JsonArray.Parse("[]"); 
Parents.Add("1", Parent); 

var Child   = JsonArray.Parse("[]"); 
Children.Add("1", Child); 

var DstParent  = (JsonArray)Parents["1"]; 
DstParent.Add(Children["1"]); 


var DstChild = (JsonArray)Children["1"]; 
JsonObject GrandChild = (JsonObject)JsonArray.Parse("{}"); 
GrandChild.Add("Age", 15); 
DstChild.Add(GrandChild); 

var Result = Parents.ToString(); 

給我: 「{」 1 「:[{」 時代 「:15}]}」

使用Newtonsoft.Json 6.0.8,家長是沒有得到的 「暗示」 該這是孩子有一個GrandChild。

var Parents   = new JObject(); 
var Children  = new JObject(); 

var Parent   = JArray.Parse("[]"); 
Parents.Add("1", Parent); 

var Child   = JArray.Parse("[]"); 
Children.Add("1", Child); 

var DstParent  = (JArray)Parents["1"]; 
DstParent.Add(Children["1"]); 


var DstChild = (JArray)Children["1"]; 
var GrandChild = JObject.Parse("{}"); 
GrandChild.Add("Age", 15); 
DstChild.Add(GrandChild); 

給我: 「{」 1 「:[[]]}」

我在做什麼錯?

回答

2

問題就出現了,因爲所有JToken對象都有一個Parent屬性,它記錄了他們在JSON對象層次結構的位置 - 但您要添加JArray Child到兩個不同的無關父母。首先,你把它添加到Children對象(這是不實際的JSON對象樹正在創建):

 Children.Add("1", Child); 

接下來你將它添加到DstParent數組(是JSON對象樹你正在創建):

 DstParent.Add(Children["1"]); 

那麼,在這種情況下Json.NET會做什麼?這既:

  1. 拋出一個異常的試圖創造一個乘父對象,或者
  2. 消費稅從原來的父對象和其移動到新的父母,或
  3. 創建的克隆它的新父對象。

事實證明,它採用選項#3:它將Children["1"]複製到DstParent。我不確定是否或在何處記錄,但從source code可以看出JContainer - 查找InsertItem,其中調用EnsureParentToken。因此,當您將您的孫子添加到DstChild時,您將其添加到原始數組而不是副本。您可以通過添加以下調試代碼看到這一點:

 Debug.WriteLine(object.ReferenceEquals(DstParent[0], DstChild)); //prints False 

簡單的定爲這是爲了避免創建Children對象,它是完全沒有必要的反正:

 var parentObj = new JObject(); 

     var parentArray = new JArray(); 
     parentObj.Add("1", parentArray); 

     var childArray = new JArray(); 
     parentArray.Add(childArray); 

     var grandChild = new JObject(); 
     grandChild.Add("Age", 15); 
     childArray.Add(grandChild); 
+0

感謝你爲這個能幹的答案。來自javascript,向多個父母添加對象不會克隆該對象。這個計劃是爲了創造功能,例如水平地做東西。爲所有的父母或所有的孩子。因此,我將這個對象添加到這些對象中...... – maol 2015-03-27 05:33:49

+1

您向我展示了我應該深入瞭解c#而不是嘗試使用JavaScript等c#的知識。 – maol 2015-03-27 05:36:28