You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#使用LINQ按属性是否存在过滤JToken的问题与实现

原有代码问题

你的代码有3个核心问题,导致运行报错或结果不符合预期:

  • 语法错误:Where 方法的lambda表达式闭合符号写错,x => x["id"] == null 末尾误用了],应该用)闭合,这个问题会直接导致编译不通过。
  • 属性判断逻辑错误:直接用x["id"] == null 无法区分「id属性不存在」和「id属性存在但值为null」两种场景,会把id值显式写为null的条目也错误归到无id列表里。
  • 容器使用错误:筛选出来的是多个JObject对象组成的列表,直接传入JObject构造函数会抛出参数异常——JObject只接收键值对形式的JProperty参数,存储对象列表应该用JArray作为容器。

另外你给出的示例数据本身也有C#语法笔误:id=2的条目后缺少逗号、数组末尾多了冗余逗号,直接运行也会报错。

正确实现代码

使用JObject.ContainsKey()方法判断id属性是否存在是最准确的,不会受id实际值的影响,同时用JArray承载列表结构即可:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Linq;

// 初始化测试数据(已修正原示例的语法笔误)
var inventory = JArray.Parse(@"[
    {""id"": 1, ""name"": ""Apple"", ""type"": ""fruit""},
    {""id"": 2, ""name"": ""Orange"", ""type"": ""fruit""},
    {""name"": ""Squash"", ""type"": ""Vegetable""}
]");

// 筛选包含id属性的令牌
List<JToken> hasIdTokens = inventory
    .Where(token => token is JObject obj && obj.ContainsKey("id"))
    .ToList();

// 筛选不包含id属性的令牌
List<JToken> noIdTokens = inventory
    .Where(token => token is JObject obj && !obj.ContainsKey("id"))
    .ToList();

// 分别序列化为JSON字符串
string hasIdJson = JsonConvert.SerializeObject(new JArray(hasIdTokens), Formatting.Indented);
string noIdJson = JsonConvert.SerializeObject(new JArray(noIdTokens), Formatting.Indented);

// 如果需要把两个列表合并为一个JSON存储,可以按如下方式组装
var saveData = new JObject
{
    ["tokensWithId"] = new JArray(hasIdTokens),
    ["tokensWithoutId"] = new JArray(noIdTokens)
};
string finalSaveJson = JsonConvert.SerializeObject(saveData, Formatting.Indented);

补充说明:代码里加了token is JObject obj的类型判断,是为了避免JToken集合中混入非对象类型的令牌(比如字符串值、数组值)时触发类型转换异常,兼容性更好。

内容的提问来源于stack exchange,提问作者newuser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 15:24:19