Powershell:作为函数参数的 PSCustomObject 数组意外更改
Powershell: PSCustomObject array as parameter in function gets changed unexpectedly
在下面简化的 PS 代码中,我不明白为什么 $MyPeople
数组在调用 changeData
函数后会发生变化。这个数组变量应该只是一个副本,我希望函数 return 另一个数组变量进入 $UpdatedPeople
而不是触摸 $MyPeople
:
function changeData {
Param ([PSCustomObject[]]$people)
$changed_people = $people
$changed_people[0].Name = "NEW NAME"
return $changed_people
}
# Original data:
$Person1 = [PSCustomObject]@{
Name = "First Person"
ID = 1
}
$Person2 = [PSCustomObject]@{
Name = "Second Person"
ID = 2
}
$MyPeople = $Person1,$Person2
"`$MyPeople[0] =`t`t" + $MyPeople[0]
"`n# Updating data..."
$UpdatedPeople = changeData($MyPeople)
"`$UpdatedPeople[0] =`t" + $UpdatedPeople[0]
"`$MyPeople[0] =`t`t" + $MyPeople[0]
控制台输出:
$MyPeople[0] = @{Name=First Person; ID=1}
# Updating data...
$UpdatedPeople[0] = @{Name=NEW NAME; ID=1}
$MyPeople[0] = @{Name=NEW NAME; ID=1}
谢谢!
PSObject2 = PSObject1
不是副本而是参考。您需要使用为此目的设计的方法克隆或复制原始对象。
function changeData {
Param ([PSCustomObject[]]$people)
$changed_people = $people | Foreach-Object {$_.PSObject.Copy()}
$changed_people[0].Name = "NEW NAME"
return $changed_people
}
上面的技术很简单,应该在这里工作。但是,它不是深度克隆。因此,如果您的 psobject 属性包含其他 psobject,您将需要考虑进行深度克隆。
我们可以克隆 PSCustomObject。我们将创建一个新的 PSObject 并通过作为参数给定的 psobject 进行枚举,并将它们一一添加到浅拷贝中。
function changeData {
Param ([PSCustomObject[]]$people)
$changed_people = New-Object PSobject -Property @{}
$people.psobject.properties | ForEach {
$changed_people | Add-Member -MemberType $_.MemberType -Name $_.Name -Value $_.Value
}
$changed_people[0].Name = 'NEW NAME'
return $changed_people
}
或使用@AdminOfThings 提供的另一种方法
在下面简化的 PS 代码中,我不明白为什么 $MyPeople
数组在调用 changeData
函数后会发生变化。这个数组变量应该只是一个副本,我希望函数 return 另一个数组变量进入 $UpdatedPeople
而不是触摸 $MyPeople
:
function changeData {
Param ([PSCustomObject[]]$people)
$changed_people = $people
$changed_people[0].Name = "NEW NAME"
return $changed_people
}
# Original data:
$Person1 = [PSCustomObject]@{
Name = "First Person"
ID = 1
}
$Person2 = [PSCustomObject]@{
Name = "Second Person"
ID = 2
}
$MyPeople = $Person1,$Person2
"`$MyPeople[0] =`t`t" + $MyPeople[0]
"`n# Updating data..."
$UpdatedPeople = changeData($MyPeople)
"`$UpdatedPeople[0] =`t" + $UpdatedPeople[0]
"`$MyPeople[0] =`t`t" + $MyPeople[0]
控制台输出:
$MyPeople[0] = @{Name=First Person; ID=1}
# Updating data...
$UpdatedPeople[0] = @{Name=NEW NAME; ID=1}
$MyPeople[0] = @{Name=NEW NAME; ID=1}
谢谢!
PSObject2 = PSObject1
不是副本而是参考。您需要使用为此目的设计的方法克隆或复制原始对象。
function changeData {
Param ([PSCustomObject[]]$people)
$changed_people = $people | Foreach-Object {$_.PSObject.Copy()}
$changed_people[0].Name = "NEW NAME"
return $changed_people
}
上面的技术很简单,应该在这里工作。但是,它不是深度克隆。因此,如果您的 psobject 属性包含其他 psobject,您将需要考虑进行深度克隆。
我们可以克隆 PSCustomObject。我们将创建一个新的 PSObject 并通过作为参数给定的 psobject 进行枚举,并将它们一一添加到浅拷贝中。
function changeData {
Param ([PSCustomObject[]]$people)
$changed_people = New-Object PSobject -Property @{}
$people.psobject.properties | ForEach {
$changed_people | Add-Member -MemberType $_.MemberType -Name $_.Name -Value $_.Value
}
$changed_people[0].Name = 'NEW NAME'
return $changed_people
}
或使用@AdminOfThings 提供的另一种方法