文档指出:
将用户定义的自定义成员添加到 Windows PowerShell 对象的实例。
“Windows PowerShell 对象”代表什么?
这工作正常:
$obj = new-object system.object
$obj | add-member -membertype noteproperty -name Name -value "OK"
$obj.name
但这不会:
$obj = @{}
实际上,我正在尝试将属性添加到 $error[0]。
文档指出:
将用户定义的自定义成员添加到 Windows PowerShell 对象的实例。
“Windows PowerShell 对象”代表什么?
这工作正常:
$obj = new-object system.object
$obj | add-member -membertype noteproperty -name Name -value "OK"
$obj.name
但这不会:
$obj = @{}
实际上,我正在尝试将属性添加到 $error[0]。
PowerShell 有所谓的 PSObject,它是任何 .NET 对象的包装器(或者它可以是完全自定义的对象),当您调用 Add-Member 时,PowerShell 会用 PSObject 隐式包装真实的 .NET 对象。
Add-Member 的工作方式取决于您是否从 PSObject 开始。如果您没有从 PSObject 开始,则 Add-Member 会将输入包装在 PSObject 中,您需要重新分配变量才能看到适应的对象。
例如:
$x = [Environment]::OSVersion
$x | Add-Member NoteProperty IsVista $true
$x | Format-List # does not show the new property
这是因为未包装的 OSVersion 是一个 PSObject。Add-Member 确实包装了它,但是该包装器丢失了,因为您没有将 $x 重新分配给包装的对象。与此行为对比:
$x = New-Object OperatingSystem ('Win32NT', '6.0')
$x | Add-Member NoteProperty IsVista $true
$x | Format-List # DOES show the new property
这是因为 New-Object 隐式地将新实例包装在 PSObject 中。因此,您的 Add-Member 调用正在将成员添加到现有包装器中。
回到第一个示例,您可以通过将其更改为:
$x = [Environment]::OSVersion
$x = $x | Add-Member NoteProperty IsVista $true -PassThru
$x | Format-List # DOES show the new property
现在毕竟,Hashtable 不能按您期望的方式工作的原因是因为 Hashtables 被 PowerShell 特殊对待,基本上 Hashtables 的适配器使用键作为属性(有点)并且 Add-Member 不会按预期工作用这种物体。