Основываясь на ответе @TeraFlux, вот функция, которая выполняет глубокое копирование нескольких объектов и принимает входные данные конвейера.
Обратите внимание, что она использует преобразование json с глубиной по умолчанию 100, что придает ейс некоторыми слабостями
- Это будет медленно на глубоких или сложных объектах или объектах с дорогими (медленными) псевдосвойствами ( методы , претендующие на свойства, которые рассчитываются на летупри запросе)
- Хотя это все равно должно быть быстрее, чем подход Add-Member, потому что тяжелая работа проходит через скомпилированную функцию
- Все, что не может бытьсохраненные в JSON могут быть повреждены или оставлены (методы будут основным кандидатом для такого типа ошибок)
- Хотя любой объект, который может безопасно пройти через этот процесс, должен быть сохраняемым, способнымбезопасно храниться (для восстановления) или вывозиться для перевозки
Я был бы заинтересован в любых оговорках илиПознакомьтесь с этими
function Clone-Object
{
[CmdletBinding()]
Param `
(
[Parameter(ValueFromPipeline)] [object[]]$objects,
[Parameter()] [int] $depth = 100
)
$clones = foreach
($object in $objects)
{
$object | ConvertTo-Json -Compress -depth $depth | ConvertFrom-Json
}
return $clones
}
Вот несколько базовых тестов
$testClone = `
{
$test1 = $null
$test2 = $null
$test3 = $null
$Test1 = [psCustomObject]@{a=1; b=2; c=3; d=4}
$Test2 = $Test1 | ConvertTo-Json -depth 100 | ConvertFrom-Json
$Test2 | add-Member -Name "e" -Value "5" -MemberType noteproperty
$Test3 = $test2 | Clone-Object
$Test3 | add-Member -Name "f" -Value "6" -MemberType noteproperty
$Test1.a = 7
$Test2.a = 8
#$Expected0 = [psCustomObject]@{a=1; b=2; c=3; d=4}
$Expected1 = [pscustomobject]@{a=7; b=2; c=3; d=4}
$Expected2 = [pscustomobject]@{a=8; b=2; c=3; d=4; e=5}
$Expected3 = [pscustomobject]@{a=1; b=2; c=3; d=4; e=5; f=6}
$results1 = @(); $results1+=$test1; $results1+=$expected1
$results2 = @(); $results2+=$test2; $results2+=$expected2
$results3 = @(); $results3+=$test3; $results3+=$expected3
$results1 | Format-Table # if these don't match then its probably passing references (copy not clone)
$results2 | Format-Table # if these don't match the core approach is incorrect
$results3 | Format-Table # if these don't match the function didn't work
}
&$testClone