从循环

时间:2017-04-25 12:11:48

标签: powershell hashtable powershell-v5.0

我确定标题不是很清楚,为此我道歉。我编写的脚本遇到了一些问题我正在编写,希望得到一些帮助,弄清楚发生了什么。我想出了如何解决这个问题,我更多地寻找为什么这种情况正在发生。该脚本长度超过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,所以我认为它是一个哈希表怪癖。

PSVersion 5.0.10586.117

1 个答案:

答案 0 :(得分:4)

  

为什么在循环结束后将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循环体相同