希望有人能够解释为什么第一次删除不影响第一个变量,但第二次删除确实影响第一个变量。谢谢你。
$X = @'
{
"$schema": "myschema",
"parameters": {
"avSetName": {
"type": "string"
},
"faultDomains": {
"type": "int",
"defaultValue": 2
}
},
"variables": {
"templateRef": "singleavset v1",
"osProfile9": "blahblah"
},
"resources": [
{
"apiVersion": "2019-07-01",
"type": "Microsoft.Compute/availabilitySets",
"name": "[parameters('avSetName')]",
"location": "[resourceGroup().location]"
}
]
}
'@
# this affects only $B...
$A = ConvertFrom-Json -InputObject $X
$B = $A.PSObject.Copy()
$A
$B
$B.PSObject.Properties.Remove( "variables" )
$A
$B
# this affects $A and $B...
$A = ConvertFrom-Json -InputObject $X
$B = $A.PSObject.Copy()
$A
$B
$B.Variables.PSObject.Properties.Remove( "osprofile9" )
$A
$B
加载 $B 时,如果我简单地使用 $B = $A 那么我明白为什么 $A 会受到影响,因为我相信 PowerShell 在幕后使用引用指针。但是,如果我使用 $B = $A.PSObject.Copy() 那么我不会期望 $A 受到影响。
类型的
[pscustomobject]
方法创建给定实例的shallow克隆(副本),而不是deep克隆(并且该类型从根本上不提供深度复制)。
因此,输入对象中的任何嵌套
[pscustomobject]
实例(由于是.NET引用类型的实例)不会被复制;具体来说,它是对它们的引用,被复制,这意味着输入对象及其副本都指向(引用)完全相同的嵌套实例。请参阅此答案了解背景信息。
具体来说,这与您的修改有关:
在您的第一次修改中,您将从复制的对象中删除属性:因为原始对象及其副本作为一个整体根据定义是不同的实例,因此此删除仅影响副本。
在第二个修改中,您将从属性 value (
.Variables.PSObject.Properties.Remove( "osprofile9" )
) 中删除属性,并且 value (.Variables
) - 由于是嵌套的 [pscustomobject]
实例 - 是 shared原始实例和副本,即它们都引用相同的实例。因此,对此嵌套实例的修改会同时出现在副本和原始实例中。
[pscustomobject]
实例的最简单方法是调用
ConvertFrom-Json
两次,并在单独的变量中捕获每个调用:
$A = ConvertFrom-Json $X
$B = ConvertFrom-Json $X