为何System.Text.Json.JsonElement未提供TryGetString()与TryGetBoolean()方法?
嘿,这个问题真的戳中了很多人刚用System.Text.Json时的疑惑——我当初第一次碰到这个点的时候也忍不住想“是不是微软漏了?”,其实背后是有设计逻辑的,咱们拆解来看:
为什么Boolean不需要TryGetBoolean?
JSON里的布尔值是强类型的,只有true和false两种明确的ValueKind(JsonValueKind.True和JsonValueKind.False)。不存在“可以转换为布尔值”的其他类型场景(比如你没法把数字1转成true,字符串"true"也不会被识别为布尔值)。所以要安全获取布尔值,直接先判断ValueKind就足够了,完全不需要Try方法:
bool targetValue = false; if (element.ValueKind is JsonValueKind.True or JsonValueKind.False) { targetValue = element.GetBoolean(); }
这种方式比Try方法更直接,成本也更低,所以设计时就没做额外的Try封装。
为什么String不需要TryGetString?
和布尔值类似,JSON字符串也是强类型的,只有当元素的ValueKind是JsonValueKind.String时,GetString()才会返回有效字符串(包括空字符串"")。如果是其他类型(比如Null、Number)调用GetString()都会抛出异常,但判断起来同样简单:
string? targetStr = null; if (element.ValueKind == JsonValueKind.String) { targetStr = element.GetString(); }
另外要注意:如果JSON里是null(ValueKind为JsonValueKind.Null),调用GetString()会直接抛异常,这时候也只需要先判断ValueKind就能规避,完全不需要Try方法的额外封装。
对比数字类型的Try方法存在的意义
像TryGetInt32()这类方法存在的原因是,JSON的Number类型是无区分的(不像C#有int、long、double)——比如一个JSON数字10.0,它的ValueKind是Number,但可以安全转换为Int32;而10.5就不行。这类数值类型的转换场景才需要Try方法来处理“可以转/不能转”的情况,而布尔和字符串没有这种跨类型转换的需求,自然不需要对应的Try方法。
总的来说这不是疏漏,而是针对不同类型的特性做的设计取舍,直接判断ValueKind就能安全处理布尔和字符串的获取啦!
内容的提问来源于stack exchange,提问作者Andy

