PowerShell中传入函数的PSCustomObject数组意外被修改问题咨询
问题解析:为什么修改函数内的数组会影响原数组?
这是一个典型的引用类型浅拷贝问题,咱们一步步拆解清楚:
核心原因:PSCustomObject是引用类型,数组赋值仅复制引用
在PowerShell里:
- 像
int、string这类属于值类型,赋值时会完整复制整个值;但PSCustomObject是引用类型,变量里存的只是指向内存中对象的指针,而非对象本身。 - 当你执行
$changed_people = $people时,并没有生成新的数组副本,只是让$changed_people和$MyPeople指向了同一个数组。更关键的是,数组里的每个元素(也就是你的Person1、Person2对象)也都是引用——所以修改$changed_people[0].Name,本质是直接修改了内存中那个原始对象的属性,自然会同步影响到$MyPeople里的对应元素。
怎么解决?创建对象的独立副本
要让函数返回新数组且不改动原数组,你需要为每个PSCustomObject创建完全独立的副本,而不是只复制数组引用。这里有两种常用方法:
方法1:用Select-Object *复制对象属性
修改你的changeData函数:
function changeData { Param ([PSCustomObject[]]$people) # 为每个对象创建属性副本,生成全新数组 $changed_people = $people | Select-Object * $changed_people[0].Name = "NEW NAME" return $changed_people }
方法2:用PSObject.Copy()直接复制对象
这是针对PSCustomObject更原生的复制方式:
function changeData { Param ([PSCustomObject[]]$people) $changed_people = $people | ForEach-Object { [PSCustomObject]$_.PSObject.Copy() } $changed_people[0].Name = "NEW NAME" return $changed_people }
测试修改后的效果
运行你原来的测试代码,会得到符合预期的输出:
$MyPeople[0] = @{Name=First Person; ID=1} # Updating data... $UpdatedPeople[0] = @{Name=NEW NAME; ID=1} $MyPeople[0] = @{Name=First Person; ID=1}
这样$MyPeople就完全不会被函数内的修改影响啦!
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

