PowerShell,根据从 JSON 结构中删除的内容,会出现意想不到的不同结果

问题描述 投票:0回答:1

希望有人能够解释为什么第一次删除不影响第一个变量,但第二次删除确实影响第一个变量。谢谢你。

    $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 受到影响。

powershell variables psobject
1个回答
0
投票

.Copy()

类型的
[pscustomobject]
方法创建给定实例的shallow克隆(副本),而不是deep克隆(并且该类型从根本上不提供深度复制)。

因此,输入对象中的任何嵌套

[pscustomobject]
实例(由于是.NET引用类型的实例)不会被复制;具体来说,它是对它们的引用,被复制,这意味着输入对象及其副本都指向(引用)完全相同的嵌套实例。请参阅此答案了解背景信息。

具体来说,这与您的修改有关:

  • 在您的第一次修改中,您将从复制的对象中删除属性:因为原始对象及其副本作为一个整体根据定义是不同的实例,因此此删除仅影响副本。

  • 在第二个修改中,您将从属性 value (

    .Variables.PSObject.Properties.Remove( "osprofile9" )
    ) 中删除属性,并且 value (
    .Variables
    ) - 由于是嵌套的
    [pscustomobject]
    实例 - 是 shared原始实例和副本,即它们都引用相同的实例。因此,对此嵌套实例的修改会同时出现在副本和原始实例中。

  • 由于您的日期源最终是 JSON,因此创建两个完全独立的
[pscustomobject]

实例的最简单方法是调用

ConvertFrom-Json
 
两次
,并在单独的变量中捕获每个调用: $A = ConvertFrom-Json $X $B = ConvertFrom-Json $X

© www.soinside.com 2019 - 2024. All rights reserved.