object ToDictionary(Type t, object obj) { var argumentTypes = refCtx.GetGenericArguments(t); var valueType = argumentTypes[1]; var res = (IDictionary)Activator.CreateInstance(t); if (obj.GetType() == typeof(Dictionary<string, object>)) { var dict = (Dictionary<string, object>)obj; foreach (var pair in dict) { res.Add(pair.Key, ToValue(valueType, pair.Value)); } } else { // obj.GetType() == typeof(List<object>) var list = (List<object>)obj; var keyType = argumentTypes[0]; foreach (var pair in list) { var pairDict = (Dictionary<string, object>)pair; res.Add(ToValue(keyType, pairDict[JsonContext.DICTIONARY_KEY_STR]), ToValue(valueType, pairDict[JsonContext.DICTIONARY_VALUE_STR])); } } return res; }
void WriteValue(object obj) { if (obj == null || obj is DBNull) { sb.Append(JsonContext.NULL); } else if (obj is bool) { sb.Append(((bool)obj) ? JsonContext.TRUE : JsonContext.FALSE); } else if (obj is string) { WriteString((string)obj); } else if (obj is char) { WriteString((char)obj); } else if (obj is int || obj is uint || obj is short || obj is ushort || obj is long || obj is ulong || obj is byte || obj is sbyte || obj is decimal) { WriteNumber((IConvertible)obj); } else if (obj is byte[]) { WriteBytes((byte[])obj); } else if (obj is Enum) { WriteEnum((Enum)obj); } else if (obj is IDictionary) { var t = obj.GetType(); if (t.IsGenericType && refCtx.GetGenericArguments(t)[0] == typeof(string)) { WriteStringDictionary((IDictionary)obj); } else { WriteDictionaryAsArray((IDictionary)obj); } } else if (obj is IEnumerable) { // must be after IDictionary since dicts are IEnumerables WriteArray((IEnumerable)obj); } else if (obj is double || obj is Double) { double a = (double)obj; if (double.IsNaN(a) || double.IsInfinity(a)) { sb.Append(JsonContext.NULL); } else { WriteNumber((IConvertible)obj); } } else if (obj is float || obj is Single) { float a = (float)obj; if (float.IsNaN(a) || float.IsInfinity(a)) { sb.Append(JsonContext.NULL); } else { WriteNumber((IConvertible)obj); } } else { WriteObject(obj); } }