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