请注意:
Windows PowerShell
C:\> ("1" | ConvertFrom-Json).gettype().name
Int32
C:\>
Powershell内核
C:\> ("1" | ConvertFrom-Json).gettype().name
Int64
C:\>
这是不好的。考虑一个键为整数的Map:
$x = @{
123 = 1
}
键123是Int32
,而不是Int64
。因此,如果123来自解析的JSON,那么它在不同的shell中会有不同的类型。现在:
C:\> $x[[Int32]123]
1
C:\> $x[[Int64]123]
C:\>
这两个shell都是如此,行为上的变化破坏了我们使用REST API操作事物的自动化脚本。
Powershell Core的这种行为可以关闭吗?
1条答案
按热度按时间cdmah0mi1#
两个PowerShell版本使用 * 不同的实现,导致您观察到的不同行为:
System.Int64
([long]
)的基本原理。System.Text.Json
将取消使用 * 单引号属性名称和字符串值的能力,Windows PowerShell和PowerShell(核心)目前都支持。从PowerShell 7.1开始,有一个计划[?]移动到现在的原生.NET JSON功能(在.NET Core 3+中可用),可通过
System.Text.Json
namespace获得,这*可能 * 在默认情况下恢复序列化到System.Int32
([int]
),考虑到破坏性的更改无论如何都是不可避免的:System.Text.Json
。System.Int64
([long]
)的数字也以不同的方式序列化(参见GitHub issue #9207):System.Decimal
([decimal]
),对于更大的数字System.Double
([double]
)。System.BigInt
([bigint]
)。0x10
),而PowerShell [Core]从v7.1 * 开始 *;然而,作为规范的另一个扩展,两者都支持 * 科学记数法 *(例如,100
的1e2
)并将其解析为[double]
。+
-前缀数字(例如,+10
),而PowerShell [Core]从v7.1开始不支持 *。解决方法:
因此,最简单的解决方法是将 * 哈希表键 * 转换为
[int]
,这允许稍后仅使用[123]
(甚至.123
)进行查找:**另一种选择是使用
[pscustomobject]
**而不是哈希表,在这种情况下,数字 keys 隐式地成为property names,它总是 * string *。这甚至适用于 numeric 变量:
[pscustomobject] @{ [int] 0x10 = 'bingo' }
会导致一个属性名为'16'
的对象。但是,请注意,哈希表/字典比
[pscustomobject]
更轻量级。[1]然而,JSON5(旨在改进JSON)确实支持hex. numbers,沿着其他值得注意的改进,例如支持注解,额外的尾随逗号和 * 单 * 引用字符串。
[2]此外,对于
[double]
值,转换是 * 文化敏感的 *,因此1.2
在某些文化中可能会导致'1.2'
(从v7.1开始,这是意想不到的-请参阅GitHub issue #14278);此外,大的[double]
s可能以 * 科学 * 表示法结束,因此1000000000000000.1
的结果是'1E+15'
。也就是说,考虑到从十进制数转换的准确性限制,使用[double]
s作为字典键通常是不明智的。