鉴于此:
$x = new-object psobject
$x | add-member noteproperty test 'xtest'
$x.test
$x | add-member noteproperty test2 'xtest2'
$x.test2
输出是我所期望的:
xtest
xtest2
但鉴于此:
$y = @{}
$y | add-member noteproperty test 'ytest'
$y.test
$y | add-member noteproperty test2 'ytest2'
$y.test2
我得到:
ytest2
我很困惑。如果我这样做:
$y = @{}
$y | add-member noteproperty test 'ytest'
$y | add-member noteproperty test2 'ytest2'
$y.test
$y.test2
然后根本没有输出。通过get-members运行确认实际上没有添加方法。
这里发生了什么?这对我来说一定是愚蠢的,但我看不到它。
答案 0 :(得分:3)
IIRC这与PSObject包装器有关,这是PowerShell 2.0中扩展类型系统的关键部分。执行此操作时:
$x = new-object psobject
$x | add-member noteproperty test 'xtest'
$x.test
它的工作原理是因为该对象已经是PSOject,所以Add-Member可以将新的NoteProperty直接添加到PSObject中,例如:
$y = @{}
$y | add-member noteproperty test 'ytest'
$y.test
这不起作用,因为$y
最初没有被包装,因此当您执行Add-Member时,它会创建一个包装原始哈希表的 new 对象。您可以使用Get-Member例如:
$y | Get-Member
您将看不到您的test
财产。要在v2中使用它,您必须这样做:
$y = $y | add-member noteproperty test ytest -passthru
$y.test
ytest
仅供参考,这在V3中有所改变,因为它基于DLR,它直接修改对象而不创建新的包装对象,例如:
# PowerShell V3 only
16# $y = @{}
17# Add-Member -InputObject $y test ytest
18# $y.test
ytest
答案 1 :(得分:0)
这是因为power shell展开了你的列表是空的。如果要将属性添加到列表,请使用inputobject参数
add-member -input $y noteproperty test1 'ytest1'
您在问题中描述的用法会为列表中的每个项目添加一个成员,您可以在此示例中看到
C:(...)SequenceId>$y = @()
C:(...)SequenceId>$y += New-Object -t psobject
C:(...)SequenceId>$y += New-Object -t psobject
C:(...)SequenceId>$Y | Add-Member -type noteproperty -name hi -value you
C:(...)SequenceId>$Y
hi
--
you
you
@Joey提出了这个问题,我使用了一个可以直接迭代的数组。要获得OP语义来执行我所说的,您必须执行下面的操作
C:(...)SequenceId>$y = @{}
C:(...)SequenceId>$y["one"] = New-Object -t psobject
C:(...)SequenceId>$y["two"] = New-Object -t psobject
C:(...)SequenceId>$Y | Add-Member -type noteproperty -name hi -value you
C:(...)SequenceId>$y
Name Value
---- -----
two
one
C:(...)SequenceId>$Y.values | Add-Member -type noteproperty -name hi -value you
C:(...)SequenceId>$y
Name Value
---- -----
two @{hi=you}
one @{hi=you}