}\r
\r
[TestMethod]\r
+ public void PropertyOrder()\r
+ {\r
+ const int count = 100;\r
+ var json = "{" + string.Join(",", Enumerable.Range(0, count).Select(n => $"\"{"a" + n}\":{n}")) + "}";\r
+ var obj = (dynamic)JsonParser.Parse(json);\r
+ var list = new List<int>();\r
+ foreach (KeyValuePair<string, dynamic> kv in obj)\r
+ list.Add((int)kv.Value);\r
+ Assert.IsTrue(list.SequenceEqual(Enumerable.Range(0, count)));\r
+ }\r
+\r
+ [TestMethod]\r
public void CastArrayToPrimitivetArray()\r
{\r
var bary = (bool[])(dynamic)JsonParser.Parse("[true,false,true]");\r
using System;\r
using System.Collections;\r
using System.Collections.Generic;\r
+using System.Collections.Specialized;\r
using System.Dynamic;\r
using System.Linq;\r
using System.Reflection;\r
private JsonObject ParseObject()\r
{\r
Consume();\r
- var dict = new Dictionary<string, JsonObject>();\r
+ var dict = new OrderedDictionary();\r
while (true)\r
{\r
var ch = NextChar();\r
private readonly double _number;\r
private readonly string _string;\r
private readonly List<JsonObject> _array;\r
- private readonly Dictionary<string, JsonObject> _dict;\r
+ private readonly OrderedDictionary _dict;\r
\r
public bool IsArray => _type == JsonType.Array;\r
public bool IsObject => _type == JsonType.Object;\r
- public bool IsDefined(string attr) => IsObject && _dict.ContainsKey(attr);\r
+ public bool IsDefined(string attr) => IsObject && _dict.Contains(attr);\r
\r
public JsonObject(bool b)\r
{\r
_array = ary;\r
}\r
\r
- public JsonObject(Dictionary<string, JsonObject> dict)\r
+ public JsonObject(OrderedDictionary dict)\r
{\r
_type = JsonType.Object;\r
_dict = dict;\r
result = null;\r
if (_type != JsonType.Object)\r
return false;\r
- if (!_dict.TryGetValue(binder.Name, out var dict))\r
+ if (!_dict.Contains(binder.Name))\r
return false;\r
- result = dict?.Value;\r
+ result = ((JsonObject)_dict[binder.Name])?.Value;\r
return true;\r
}\r
\r
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)\r
{\r
- result = _type == JsonType.Object && _dict.ContainsKey(binder.Name);\r
+ result = _type == JsonType.Object && _dict.Contains(binder.Name);\r
return true;\r
}\r
\r
result = _array[(int)indexes[0]]?.Value;\r
return true;\r
case JsonType.Object:\r
- result = _dict[(string)indexes[0]]?.Value;\r
+ result = ((JsonObject)_dict[(string)indexes[0]])?.Value;\r
return true;\r
}\r
result = null;\r
result = _array.Select(x => x.Value);\r
return true;\r
case JsonType.Object:\r
- result = _dict.Select(x => new KeyValuePair<string, dynamic>(x.Key, x.Value));\r
+ result = _dict.Cast<DictionaryEntry>().Select(x => new KeyValuePair<string, dynamic>((string)x.Key, x.Value));\r
return true;\r
default:\r
result = null;\r
case IEnumerable arry:\r
return new JsonObject(arry.Cast<object>().Select(CreateJsonObject).ToList());\r
case object obj:\r
- return new JsonObject(obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)\r
- .ToDictionary(prop => prop.Name, prop => CreateJsonObject(prop.GetValue(obj))));\r
+ var dict = new OrderedDictionary();\r
+ foreach (var prop in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))\r
+ dict.Add(prop.Name, CreateJsonObject(prop.GetValue(obj)));\r
+ return new JsonObject(dict);\r
}\r
return null;\r
}\r
case JsonType.Object:\r
sb.Append("{");\r
delimiter = "";\r
- foreach (var entry in _dict)\r
+ foreach (DictionaryEntry entry in _dict)\r
{\r
sb.Append(delimiter);\r
sb.Append("\"");\r
}\r
else\r
{\r
- entry.Value.ConvertToString(sb);\r
+ ((JsonObject)entry.Value).ConvertToString(sb);\r
}\r
delimiter = ",";\r
}\r