6

ExpandoObject に変換したい JSON オブジェクト (複数レベルの JSON 配列などを含む場合があります) を取得しています。

IDictionary を実装しているため、実行時に単純なプロパティを ExpandoObject に追加する方法を理解しましたが、実行時に正しく解決されるネストされたプロパティ (たとえば、 のようなものmyexpando.somelist.anotherlist.someitem)を追加するにはどうすればよいですか?

編集:現在、これは単純な(最初のレベルの)プロパティでうまく機能します:

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

問題は、名前をネストして、それに応じて ExpandoObject を解決する方法です。

4

4 に答える 4

8
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";
于 2014-07-09T06:59:17.223 に答える
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"
于 2012-11-30T22:29:30.367 に答える
1

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動的オブジェクトの作成時にコンストラクターによって設定され、直後の最後の参照ディクショナリとして設定されます。これは、 Dictionary がクラスであり、したがって参照型であるという事実により機能します。

次に、正しくネストするには、多次元配列と同様に、各ネスト レベルで各辞書をインスタンス化する必要があります。例えば:

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、私はそれを必要としなかったので追加しませんでした。

于 2012-12-22T07:21:34.760 に答える