从jarray中删除指定元素的问题

string jsonText = "[{\"a\": \"aaa\",\"b\": \"bbb\",\"c\": \"ccc\"},{\"a\": \"aa\",\"b\": \"bb\",\"c\": \"cc\"}]";
            var mJObj = JArray.Parse(jsonText);
            //需求,删除列表里的a节点的值为\"aa\"的项
            IList<JToken> _ILIST = new List<JToken>(); //存储需要删除的项
            JArray _JARRAY = new JArray();

            foreach (var ss in mJObj)  //查找某个字段与值
            {
                if ((((JObject)ss)["a"]).ToString() == "aa")
                {
                    _ILIST.Add(ss);
                    _JARRAY.Add(ss);

                    Console.Write(_ILIST[0]);
                    Console.Write(_ILIST[0].GetHashCode());
                    Console.Write("\r\n---------------------------\r\n");
                    Console.Write("\r\n---------------------------\r\n");
                    Console.Write(_JARRAY[0]);
                    Console.Write(_JARRAY[0].GetHashCode());
                    Console.Write("\r\n---------------------------\r\n");
                    Console.Write("\r\n---------------------------\r\n");
                    Console.Write(mJObj[1].GetHashCode());
                   
                }
            }

            foreach (var item in _ILIST)  //移除mJObj  有效
            {
                mJObj.Remove(item);
            }
            foreach (var item in _JARRAY)  //移除mJObj  无效
            {
                mJObj.Remove(item);
            }
View Code

通过_ILIST删除是有效的。

通过_JARRAY删除是无效的。

 

感谢怪蜀黍(Q:390647417)的解惑~

因为mJObj是一个JArray,实现了 IList<JToken>, 所以这里的ss就是JToken类型,把它add到_ILIST这样一个List<JToken>里,非常适合。
但是你如果调用 _JARRAY.Add(ss), 把JToken加到JArray里,就会把这个JToken从原来它所属的JObject上“拆”下来,所以ss的Root在Add之后变了。
 
所以,本质上,这个是一个json的数据格式的设计问题。我觉得这样很合理。
 
 

 总结:不同对象的Add方法并不保证原来是啥样,加进去还是啥样。

加进去的对象。在类型,值,ToString(),GetHash值,Root等方面,可能或多或少存在不同的地方。

所以以后遇到这种“诡异”的情况的时候,第一时间要想到是Add出了问题

posted on 2017-06-14 22:45  落忆无痕  阅读(1617)  评论(0编辑  收藏  举报

导航