Powershell显示JSON对象和地址属性的错误输出
我目前正在努力将JSON字符串转换为对象数组,并处理每个对象的属性 下面是一个简单的演示,它显示了例如属性“address”似乎有点特殊:Powershell显示JSON对象和地址属性的错误输出,json,powershell,convertfrom-json,member-enumeration,Json,Powershell,Convertfrom Json,Member Enumeration,我目前正在努力将JSON字符串转换为对象数组,并处理每个对象的属性 下面是一个简单的演示,它显示了例如属性“address”似乎有点特殊: cls $json = '[{"id":"1","address":"1"},{"id":"2","address":"2"}]' $list = $json | ConvertFrom-Json $list.id # OK $list.address # gives a weire
cls
$json = '[{"id":"1","address":"1"},{"id":"2","address":"2"}]'
$list = $json | ConvertFrom-Json
$list.id # OK
$list.address # gives a weired result - is this a bug?
$list.GetEnumerator().address # that works
这是输出:
1
2
OverloadDefinitions
-------------------
System.Object&, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Address(int )
1
2
如您所见,我需要添加“.GetEnumerator()”以获得正确的“地址”值
这是预期的吗?我是否应该始终使用“.GetEnumerator()”以确保安全?因为
$list
是一个数组(集合),使用类似$list.id
的东西执行;也就是说,在每个元素上自动访问.id
属性,结果值作为数组返回([object[]]
)[1]
但是,如果数组/集合类型本身有一个同名的成员(属性或方法),则它优先于,这就是您的情况:.NET数组有一个.Address
方法(由运行时添加-请参阅),这就是抢占访问元素的.Address
属性的原因
(您看到的是PowerShell对方法签名(重载)的表示,这是当您仅按名称访问方法,而不通过附加((…)
)实际调用它时得到的;请尝试'foo'.ToUpper
,例如)
PowerShell没有提供明确的运算符语法来区分直接成员访问和成员枚举,这是[GitHub issue#7445]的主题(https://github.com/PowerShell/PowerShell/issues/7445),但现有的行为不太可能改变。
解决该问题的最有效方法是使用PSv4+数组方法,该方法始终以集合的元素为目标:
注意事项:如果运行的是Windows PowerShell和$list
可能会在某种情况下生成单个pscustomobject
而不是数组,则必须将$list
括在数组子表达式操作符@(…)
中,以确保.ForEach()
方法可用。这是一个特定于[pscustomobject]
的bug(考虑到即使是单个对象也应该始终有一个.ForEach()
方法),它已在PowerShell(Core)6+中得到修复
# @(...) is necessary in Windows PowerShell only.
@($list).ForEach('address')
注:
- 从技术上讲,这将返回一个
集合,但在大多数情况下,您可以像常规[System.Collections.ObjectModel.Collection[PSObject]]]
PowerShell数组一样使用它[object[]]
- 与成员枚举不同,如果输入集合中只有一个元素,则也会返回集合实例(而不是像成员枚举那样返回该元素的属性值)
在PSv3-中,可以使用
ForEach-Object
cmdlet,或Select-Object-ExpandProperty
:
$list | ForEach-Object address # PSv2: | ForEach-Object { $_.address }
# OR
$list | Select-Object -ExpandProperty address
[1] 如果集合中只有一个元素,则其属性值按原样返回,而不是包装在(单个元素)数组中,这与在变量中收集管道输出时应用的逻辑相同。此逻辑在成员枚举的上下文中可能是意外的,这是一个表达式上下文,在中讨论。
Address
解析为$list
-do$list |%Address
中包含的数组的Address
属性
$list | ForEach-Object address # PSv2: | ForEach-Object { $_.address }
# OR
$list | Select-Object -ExpandProperty address