2012-11-30 121 views
0

我得到一個JSON對象(可能包含多個JSON數組等級),我想要將其轉換爲ExpandoObject。動態添加嵌套屬性ExpandoObject

我想通了如何在運行時簡單的屬性添加到ExpandoObject因爲它實現IDictionary的,但我怎麼添加嵌套屬性(例如,像myexpando.somelist.anotherlist.someitem)在運行時,將正確的解決?

編輯:目前,這適用於簡單的(第一級)性能好:

var exo = new ExpandoObject() as IDictionary<String, Object>; 
exo.Add(name, value); 

的問題是如何去嵌套的名稱和ExpandoObject相應解決。

+1

亞歷克斯,考慮你以前的問題,我認爲你需要DynamicObject而不是ExpandoObject。請參閱[本](http://pastebin.com/6b2fLChA)及其[樣本](http://pastebin.com/JEYfgL3a) –

回答

1

如何做這樣的:

var exo = new ExpandoObject() as IDictionary<String, Object>; 
var nested1 = new ExpandoObject() as IDictionary<String, Object>; 

exo.Add("Nested1", nested1); 
nested1.Add("Nested2", "value"); 

dynamic d = exo; 
Console.WriteLine(d.Nested1.Nested2); // Outputs "value" 
0

您可以通過存儲先前獲取的對象,或字典,當TryGetValue被稱爲參考做到這一點。我用一個類,如下所示:

public DynamicFile(IDictionary<string, object> dictionary) 
{ 
    if (dictionary == null) 
     throw new ArgumentNullException("dictionary"); 
    _dictionary = dictionary; 
    _lastGetRef = _dictionary; 
} 

private readonly IDictionary<string, object> _dictionary; 
private IDictionary<string, object> _lastGetRef; 

public override bool TryGetMember(GetMemberBinder binder, out object result) 
{ 
    if (!_dictionary.TryGetValue(binder.Name, out result)) 
    { 
     result = null; 
     return true; 
    } 

    var dictionary = result as IDictionary<string, object>; 
    if (dictionary != null) 
    { 
     result = new DynamicFile(dictionary); 
     _lastGetRef = dictionary; 
     return true; 
    } 

    return true; 
} 

public override bool TrySetMember(SetMemberBinder binder, object value) 
{ 
    if(_dictionary.ContainsKey(binder.Name)) 
     _dictionary[binder.Name] = value; 
    else if (_lastGetRef.ContainsKey(binder.Name)) 
     _lastGetRef[binder.Name] = value; 
    else 
     _lastGetRef.Add(binder.Name, value); 

    return true; 
} 

_dictionary是由構造函數設置創建動態對象,然後設置爲眼前的最後一個引用字典時。這是因爲Dictionarys是類和因此引用類型的事實。

然後爲了正確嵌套,您需要在每個嵌套級別實例化每個字典,就像多維數組一樣。例如:

myexpando.somelist = new Dictionary<string, object>(); 
myexpando.somelist.anotherlist = new Dictionary<string, object>(); 
myexpando.somelist.anotherlist.someitem = "Hey Hey There! I'm a nested value :D"; 

你也許可以編寫一些代碼在TryGetMember即會自動添加該鍵不存在一個字典,但我並不需要一個,所以我沒有添加。

2
dynamic myexpando = new ExpandoObject(); 
myexpando.somelist = new ExpandoObject() as dynamic; 
myexpando.somelist.anotherlist = new ExpandoObject() as dynamic; 
myexpando.somelist.anotherlist.someitem = "Hey Hey There! I'm a nested value :D";