arrays - Powershell - 为每个对象调用函数时的奇怪行为会更改所有对象中的数组
问题描述
我遇到了一些我无法解决的奇怪问题,所以希望有人能对此有所了解。不知道为什么,但是我对函数中对象的数组所做的任何事情都会影响/改变其他对象数组。
这就是我所做的。我描述对象类:
Class testObject {
[array] $list
[int] $increment }
然后我创建两个具有相同 $list 的对象:
$numberList = (1,1,1,1,1,1,1,1,1)
$obj1 = New-Object testObject
$obj1.list = $numberList
$obj1.increment = 2
$obj2 = New-Object testObject
$obj2.list = $numberList
$obj2.increment = 5
接下来,我将描述将每个数组项增加每个对象中指定的增量值的函数:
Function Increase-numbers ($obj) {
[array] $array = $obj.list
For ($i = 0; $i -lt 9; ++$i) {
$array[$i] += $obj.increment }
$obj.list = $array
return $obj
}
然后我运行将对象传递给函数的函数,并使用函数结果更新对象:
$obj1 = Increase-numbers $obj1
Write-Host "$($obj1.list)"
$obj2 = Increase-numbers $obj2
Write-Host "$($obj2.list)"
我希望返回的值是: 对于 $obj1(增量值 = 2):333333333 对于 $obj2(增量值 = 5):666666666
但它实际上返回:333333333 888888888
发生这种情况是因为在我更改数组值的第一个函数调用中,它也会自动更新 $obj2 数组值。
有谁知道我做错了什么?
解决方案
编辑:正如下面提到的@mklement0,最有可能的做法是:
# other code here
$obj1.list = $numberList.Clone() # Instead of $numberList.PsObject.Copy()
# other code here
$obj2.list = $numberList.Clone() # Instead of $numberList.PsObject.Copy()
# other code here
这是提供的解释:
我建议使用 $numberList.Clone(),不仅因为它比有点晦涩难懂的 .psobject.Copy() 更简单,而且因为后者可能给人一种错误的印象,即它是一种通用的对象克隆机制,而事实并非如此。 t - 任何不是 [pscustomobject] 或实现 ICloneable 的引用类型的实例都将按原样返回 - 换句话说:调用实际上是一个安静的无操作。例如,它适用于可散列({ ... }),但不适用于有序品种([ordered] @{ ... })
原答案:
发生这种情况是因为您是$numberList
按引用复制,而不是按值复制。一旦您增加了第一个值,Increase-numbers
它就会为引用该列表的所有变量增加它。
如果你改变:
# other code here
$obj1.list = (1,1,1,1,1,1,1,1,1)
# other code here
$obj2.list = (1,1,1,1,1,1,1,1,1)
# other code here
对此:
# other code here
$obj1.list = $numberList.PsObject.Copy()
# other code here
$obj2.list = $numberList.PsObject.Copy()
# other code here
它应该对您有用,因为您正在复制$numberList
按值,到$obj1.list
- 按值复制将其视为一个全新的变量。您也可以执行以下操作:
# other code here
$obj1.list = (1,1,1,1,1,1,1,1,1)
# other code here
$obj2.list = (1,1,1,1,1,1,1,1,1)
# other code here
或者..
$numberList1 = (1,1,1,1,1,1,1,1,1)
$numberList2 = $numberList1.PsObject.Copy()
# other code here
$obj1.list = $numberList1
# other code here
$obj2.list = $numberList2
# other code here
或者..
$numberList1 = (1,1,1,1,1,1,1,1,1)
$numberList2 = (1,1,1,1,1,1,1,1,1)
# other code here
$obj1.list = $numberList1
# other code here
$obj2.list = $numberList2
# other code here