为什么在Powershell中使用内置类型的add-member的奇怪行为发生了?

时间:2012-03-28 19:30:33

标签: powershell

鉴于此:

$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运行确认实际上没有添加方法。

这里发生了什么?这对我来说一定是愚蠢的,但我看不到它。

2 个答案:

答案 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}