【问题标题】:PowerShell Hashtable values being removed from second hashtable outside of loop从循环外的第二个哈希表中删除 PowerShell 哈希表值
【发布时间】:2017-04-25 12:11:48
【问题描述】:

我确定标题不是很清楚,对此我深表歉意。我在编写脚本时遇到了一些问题,希望能得到一些帮助来弄清楚发生了什么。我想出了如何解决这个问题,我正在寻找为什么会发生这种情况。该脚本超过 3k 行,但我在下面写的 sn-p 重现了同样的问题。

我有三个哈希表,DeviceList、AllDevices 和 RemovedDevices。 Devicelist 是明确布局的,AllDevices 等于 DeviceList。在一个循环中,RemovedDevices 中存在的项目将从 DeviceList 中删除。尽管 AllDevices 在此示例中仅在开头进行了修改,但仍会从中删除设备。

$DeviceList = @{"server1" = "email1"; "server2" = "email2"; "server3" = "email3"}
$AllDevices = $DeviceList
$RemovedDevices = @{"server1" = "email1"; "server2" = "email2"}

foreach($RemovedDevice in $RemovedDevices.GetEnumerator())
  {
  $DeviceList | where {$_.ContainsKey($RemovedDevice.Key)} | % {$_.Remove($RemovedDevice.Key)}
  }
$AllDevices

运行上述文本,$AllDevices 被修改为仅包含 server3 信息,它仍应包含所有 3 个服务器。

如果我将第二行修改为:

$AllDevices += $DeviceList

然后 AllDevices 维护所有 3 个值。在第一个版本上使用断点并单步执行,我已经验证 AllDevices 在第一次之后没有被命中。

我的总体问题是:为什么在循环结束后将 AllDevices 修改为等于 DeviceList?如果它在开始时只调用一次,那么尽管对 DeviceList 进行了修改,它的值不应该保持不变吗?使用类似方法重建数组不会覆盖 AllDevices 所以我想这是一个哈希表怪癖。

PSVersion 5.0.10586.117

【问题讨论】:

    标签: powershell hashtable powershell-5.0


    【解决方案1】:

    为什么在循环结束后 AllDevices 被修改为等于 DeviceList?

    因为$AllDevices 只是对与$DeviceList 相同的底层对象的引用

    如果它在一开始只被调用一次,那么它的值是否应该保持不变,尽管对 DeviceList 进行了修改?

    如果$AllDevices 是一个相同 对象,当然可以,但它不仅仅是相同的——它同一个对象。

    幸运的是,哈希表实现了ICloneable接口,所以对于浅层哈希表,可以使用Clone()方法:

    $DeviceList = @{"server1" = "email1"; "server2" = "email2"; "server3" = "email3"}
    $AllDevices = $DeviceList.Clone()
    
    $RemovedDevices = @{"server1" = "email1"; "server2" = "email2"}
    
    foreach($RemovedDevice in $RemovedDevices.GetEnumerator())
    {
        if($DeviceList.ContainsKey($RemovedDevice.Key))
        {
            $DeviceList.Remove($RemovedDevice.Key)
        }
    }
    $AllDevices
    

    我发现使用带有 Where-Object 的哈希表超级不可读(更不用说不必要的慢了),但在功能上,上面的内容与您原来的 foreach 循环体相同

    【讨论】:

    • 我从来不知道这样做只是一个引用而不是一个单独的对象。非常感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 2023-04-09
    相关资源
    最近更新 更多