.NET 6中排序JsonArray触发InvalidOperationException问题排查
执行排序代码时出现以下错误:
System.InvalidOperationException: failed to compare two elements in the array.
Inner Exception: ArgumentException: at least one object must implement IComparable
我需要对包含JsonObject的JsonArray按startTime属性排序,确认所有对象类型一致,在Visual Studio的Locals窗口中可见arrayToSort包含104个JsonObject,调试发现遇到最后一个startTime为0的元素时触发错误,使用.NET 6.0。
我的代码如下:
private JsonArray sortOnStartTime(JsonArray arrayToSort) { var testArray = arrayToSort.OrderBy(x => x["startTime"]); //breakpoint here // return (JsonArray)JsonNode.Parse(JsonSerializer.Serialize(arrayToSort.OrderBy(x => x["startTime"]))); return new JsonArray(); }
异常原因与元素差异
问题核心是x["startTime"]返回的是JsonNode类型,而JsonNode本身未实现IComparable接口,LINQ的OrderBy无法直接比较两个JsonNode对象。
你遇到的最后一个startTime为0的元素,大概率和其他元素的startTime存储类型不一致:比如其他元素的startTime是字符串格式的时间戳(如"1620000000"),而这个元素是数值类型的0;或者反之。这种类型不匹配会导致比较逻辑崩溃,触发异常。
解决方法
1. 强类型转换排序键
将startTime转换为可比较的具体类型(如数值型或DateTime),确保所有元素都能正确转换:
// 若startTime是数值型时间戳 var testArray = arrayToSort.OrderBy(x => long.Parse(x["startTime"].ToString())); // 若startTime是ISO格式字符串时间 var testArray = arrayToSort.OrderBy(x => DateTime.Parse(x["startTime"].ToString()));
2. 使用JsonNode的GetValue方法(推荐)
.NET 6的JsonNode提供了GetValue<T>方法,可安全获取强类型值,避免类型转换错误:
var testArray = arrayToSort.OrderBy(x => x["startTime"].GetValue<long>());
如果存在类型不确定的情况,可增加判断逻辑处理异常:
var testArray = arrayToSort.OrderBy(x => { var startTimeNode = x["startTime"]; return startTimeNode is JsonValue valueNode ? valueNode.GetValue<long>() : long.MaxValue; });
3. 修正返回逻辑
最终完整的排序方法可调整为:
private JsonArray sortOnStartTime(JsonArray arrayToSort) { var sortedNodes = arrayToSort.OrderBy(x => x["startTime"].GetValue<long>()).ToList(); var sortedArray = new JsonArray(); foreach (var node in sortedNodes) { sortedArray.Add(node); } return sortedArray; }
内容的提问来源于stack exchange,提问作者Cooz

