Как клонировать переменную PowerShell PSCustomObject, чтобы отключить ее от другой переменной?
Я ищу лучшее решение для следующей проблемы. Этот код:
$a = "{value:'1'}" | ConvertFrom-Json
$b = $null
Write-Output ("a: {0} - b: {1}" -f $a, $b)
$b = $a
Write-Output ("a: {0} - b: {1}" -f $a, $b)
$a.value = '2'
Write-Output ("a: {0} - b: {1}" -f $a, $b)
$b.value = '3'
Write-Output ("a: {0} - b: {1}" -f $a, $b)
Возвращает это:
a: @ {value = 1} - b: a: @ {value = 1} - b: @ {value = 1} a: @ {value = 2} - b: @ {value = 2} a: @ {value = 3} - b: @ {value = 3}
Что мне нужно, это: после настройки $b
в $a
Я должен быть в состоянии изменить $a
в то время как $b
остается неизменной.
Единственное решение, которое я мог бы придумать, - это выполнить преобразование в JSON и обратно, например:
$a = "{value:'1'}" | ConvertFrom-Json
$b = $null
Write-Output ("a: {0} - b: {1}" -f $a, $b)
$b = $a | ConvertTo-Json -depth 100 | ConvertFrom-Json
Write-Output ("a: {0} - b: {1}" -f $a, $b)
$a.value = '2'
Write-Output ("a: {0} - b: {1}" -f $a, $b)
$b.value = '3'
Write-Output ("a: {0} - b: {1}" -f $a, $b)
Это возвращает мой желаемый результат:
a: @ {value = 1} - b: a: @ {value = 1} - b: @ {value = 1} a: @ {value = 2} - b: @ {value = 1} a: @ {value = 2} - b: @ {value = 3}
Я ищу лучшее решение, потому что в моем реальном примере переменными являются большие файлы JSON, которые загружаются с диска, обновляются и сохраняются через PUT в API.
Обновление: PSObject.Copy()
не решает мою реальную проблему из-за того, что JSON имеет вложенные объекты (как предсказывал Ансгар Вихерс в своем ответе).
Посмотрите этот пример для различия в поведении между ConvertTo/From-Json и PSObject.Copy():
$a = "{value:'1',nested:{foo:'original value'}}" | ConvertFrom-Json
$b = $a | ConvertTo-Json -depth 100 | ConvertFrom-Json
$a.nested.foo = 'changing $a does not change $b'
$b | ConvertTo-Json -Depth 1
$c = $a.PSObject.Copy()
$a.nested.foo = 'changing $a changes $c!'
$c | ConvertTo-Json -Depth 1
Результат:
{
"value": "1",
"nested": {
"foo": "original value"
}
}
{
"value": "1",
"nested": {
"foo": "changing $a changes $c!"
}
}
Обновление 2: код в другом вопросе, который мой вопрос помечен как дубликат, действительно работает в моем случае (см. Ниже), но я буду придерживаться моего ConvertTo/From-Json, потому что это намного проще...
$a = "{value:'1',nested:{foo:'original value'}}" | ConvertFrom-Json
$ms = New-Object System.IO.MemoryStream
$bf = New-Object System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
$bf.Serialize($ms, $a)
$ms.Position = 0
$b = $bf.Deserialize($ms)
$ms.Close()
$a.nested.foo = 'changing $a does not change $b'
$b | ConvertTo-Json -Depth 1
Результат:
{
"value": "1",
"nested": {
"foo": "original value"
}
}