using System.Collections.Generic;
using System.Collections;
public static void Main()
dynamic model = ChoExpandoObject.New("performanceLevels",
new List<ChoExpandoObject>
ChoExpandoObject.New("performanceLevel_1",
ChoExpandoObject.New(new string[] { "title", "version", "threelevels" },
ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"string", "column", "title-column", "N/A"),
ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"int", "column", "version-column", "1"),
ChoExpandoObject.New("version",
ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"int", "column", "version-column", "1")
ChoExpandoObject.New("performanceLevel_2",
new List<ChoExpandoObject>
ChoExpandoObject.New("title", ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"string", "column", "title-column", "N/A")
ChoExpandoObject.New("version", ChoExpandoObject.New(new string[] { "data-type", "source", "source-column", "default" },
"int", "column", "version-column", "1")
var settings = new JsonSerializerSettings()
Converters = new List<JsonConverter> { },
Formatting = Formatting.Indented
var jsonMap = JsonConvert.SerializeObject(new List<ChoExpandoObject> { model }, settings);
Console.WriteLine(jsonMap);
public class ChoExpandoObject : DynamicObject, IDictionary<string, object>
private readonly object _padLock = new object();
private IDictionary<string, object> _kvpDict = new Dictionary<string, object>();
#endregion Instance Members
public ChoExpandoObject()
public ChoExpandoObject(IDictionary<string, object> kvpDict)
#region DynamicObject Overrides
public override bool TryGetMember(GetMemberBinder binder, out object result)
return GetPropertyValue(binder.Name, out result);
public override bool TrySetMember(SetMemberBinder binder, object value)
return SetPropertyValue(key, value);
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
if ((indexes.Length == 1) && indexes[0] != null)
if (indexes[0] is string)
var key = indexes[0] as string;
return GetPropertyValue(key, out result);
else if (indexes[0] is int)
var index = (int)indexes[0];
IDictionary<string, object> kvpDict = _kvpDict;
result = kvpDict.ElementAt(index).Value;
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
if ((indexes.Length == 1) && indexes[0] != null)
if (indexes[0] is string)
var key = indexes[0] as string;
return SetPropertyValue(key, value);
else if (indexes[0] is int)
var index = (int)indexes[0];
IDictionary<string, object> kvpDict = _kvpDict;
kvpDict[kvpDict.ElementAt(index).Key] = value;
#endregion DynamicObject Overrides
#region Instance Members (Protected/Public)
protected virtual bool GetPropertyValue(string name, out object result)
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict.ContainsKey(name))
protected virtual bool SetPropertyValue(string name, object value)
IDictionary<string, object> kvpDict = _kvpDict;
if (!kvpDict.ContainsKey(name))
kvpDict.Add(name, value);
public static ChoExpandoObject New(Func<IEnumerable<KeyValuePair<string, object>>> func)
Dictionary<string, object> dict = new Dictionary<string, object>();
foreach (var kvp in func())
dict.Add(kvp.Key, kvp.Value);
return new ChoExpandoObject(dict);
public static ChoExpandoObject New(string key, object value)
Dictionary<string, object> dict = new Dictionary<string, object>();
return new ChoExpandoObject(dict);
public static ChoExpandoObject New(string[] keys, params object[] values)
Dictionary<string, object> dict = new Dictionary<string, object>();
foreach (var key in keys)
if (counter < values.Length)
dict.Add(key, values[counter]);
return new ChoExpandoObject(dict);
public ICollection<string> Keys
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict != null ? kvpDict.Keys : null;
public ICollection<object> Values
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict != null ? kvpDict.Values : null;
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict != null ? kvpDict.Count : 0;
public object this[string key]
GetPropertyValue(key, out result);
SetPropertyValue(key, value);
public bool ContainsKey(string key)
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict.ContainsKey(key);
public void Add(string key, object value)
SetPropertyValue(key, value);
public bool Remove(string key)
IDictionary<string, object> kvpDict = _kvpDict;
if (kvpDict != null && kvpDict.ContainsKey(key))
public bool TryGetValue(string key, out object value)
return GetPropertyValue(key, out value);
public void Add(KeyValuePair<string, object> item)
SetPropertyValue(item.Key, item.Value);
IDictionary<string, object> kvpDict = _kvpDict;
public bool Contains(KeyValuePair<string, object> item)
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict.Contains(item);
public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
IDictionary<string, object> kvpDict = _kvpDict;
foreach (var kvp in kvpDict)
array[arrayIndex++] = kvp;
public bool Remove(KeyValuePair<string, object> item)
IDictionary<string, object> kvpDict = _kvpDict;
return kvpDict.Contains(item);
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
IDictionary<string, object> kvpDict = _kvpDict;
foreach (var kvp in kvpDict)
IEnumerator IEnumerable.GetEnumerator()
public override IEnumerable<string> GetDynamicMemberNames()