文档中remarks 中的注释似乎暗示了答案(但未完全解释):
此方法不解析 JSON 字符串值的内容。
但是直到我找到一些comments in a github issue 描述这些方法之前,我仍然感到困惑。这是该评论的 sn-p(略微省略,** 由我添加):
// InvalidOperationException if Type is not True or False
public bool GetBoolean();
// InvalidOperationException if Type is not Number
// FormatException if value does not fit
public decimal GetDecimal();
public double GetDouble();
public int GetInt32();
// InvalidOperationException if Type is not Number
// false if value **does not fit.**
public bool TryGetDecimal(out decimal value);
public bool TryGetDouble(out double value);
public bool TryGetInt32(out int value);
所以,最终归结为FormatException 和InvalidOperationException 之间的区别。
后者用于表示令牌的ValueKind(数字、字符串、真、假)与预期类型不匹配。前者 (FormatException) 的使用与人们通常期望的有所不同;而不是因为解析错误而被抛出*(即“1.sg”不是int),而是因为超出范围错误!
如果我们首先查看数字重载,则可以更好地理解这一点。非Try 变体要么返回一个值,要么抛出两个异常之一:InvalidOperationException 如果值不是数字,FormatExceptions 如果它们不适合。来自GetInt32 的文档:
例外情况
InvalidOperationException
此值的 ValueKind 不是 Number。
FormatException
该值不能表示为Int32。
将此与抛出一个异常的Try 变体进行比较——如果类型不是数字,则为InvalidOperationException——但如果值不合适,则返回 false。来自TryGetInt32的文档:
例外情况
InvalidOperationException
此值的 ValueKind 不是 Number。
退货
如果数字可以表示为 Int32,则为布尔值 true;否则,false。
在这种情况下,“不适合”意味着该值对于基础类型来说太大/太小,即。使用[Try]GetInt32时大于int.MaxValue
现在让我们回到booleans 的情况,您已经正确地注意到只有一个非Try 变体。查看同一个 github 问题中的 cmets,我们会看到:
// InvalidOperationException if Type is not True or False
public bool GetBoolean();
还有文档:
例外情况
InvalidOperationException
此值的 ValueKind 既不是 True 也不是 False。
这里缺少的是FormatException 和“不适合”的情况。正如我们在上面在数字的情况下看到的那样,Try 变体让我们检测到“是的,这是一个数字,但它超出了适当的范围”。 Booleans 只有两个可能的值——true 和 false——没有可检测的范围,也没有可区分的 FormatException。与 strings 类似——它要么是 string 令牌,要么不是。
需要注意的重要一点是,在所有情况下,如果 ValueKind 与方法所期望的不匹配,则会抛出 InvalidOperationException。假设的TryGetBoolean 不会返回false,如果遇到“abc”的string 值,它会抛出InvalidOperationException,因为ValueKind 不是True 或False。 但这已经是 GetBoolean 所做的了! 所以不需要单独的方法。
* 注意:没有解析错误,因为这些方法实际上并没有尝试解析 json string 令牌内的数字/布尔值,它们只考虑值正确的令牌类型。换句话说,目前不支持引用的数字/布尔值:
{
"number": 1234,
"notNumber": "1234",
"bool": true,
"notBool": "false"
}
目前 (2020-05-30) 有一个 request to add support 用于此。届时我们可能会看到 TryGet 方法的可用性/功能发生变化。