从循环外的第二个哈希表中删除 PowerShell 哈希表值

PowerShell Hashtable values being removed from second hashtable outside of loop

我确定标题不是很清楚,为此我深表歉意。我 运行 遇到了一个我正在编写的脚本的问题,希望得到一些帮助来弄清楚发生了什么。我想出了解决问题的方法,我更想知道 为什么 会发生这种情况。脚本超过 3k 行,但我在下面写的代码片段重现了同样的问题。

我有三个哈希表,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 所以我想这是一个哈希表怪癖。

PS 版本 5.0.10586.117

Why is AllDevices being modified to equal DeviceList after the loop has finished?

因为 $AllDevices 只是 对与 $DeviceList

相同的底层对象的引用

If it's only called once at the beginning, shouldn't it's value remain static despite modifications to 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 循环体相同