HashTable具有无穷无尽的深度。为什么?怎么避免?

时间:2016-09-29 19:33:22

标签: powershell powershell-v4.0

当我使用$ emptyHashTable变量创建一个空的哈希表时,它似乎生成了一个无穷无尽的深度哈希表。无法弄清楚原因 当我使用@ {}时,它的工作正确。

代码示例

cls

$L1     = "L1"
$emptyHashTable = @{}

# Correct, hashtable contains 1 sub-hashtable
$proj1       = @{}
$proj1."$L1" = @{}

# Wrong, endless hashtable depth
$proj2       = @{}
$proj2."$L1" = $emptyHashTable

# Wrong, endless hashtable depth
$proj3       = $emptyHashTable
$proj3."$L1" = @{}

# Wrong, endless hashtable depth
$proj4       = $emptyHashTable
$proj4."$L1" = $emptyHashTable

Write-Host
Write-Host "proj1"
Write-Host "Level 0: " $proj1.GetType()
Write-Host "Level 1: " $proj1.L1.GetType()
Write-Host "Level 2: " $proj1.L1.L1.GetType() # Will generate error: You cannot call a method on a null-valued expression.
Write-Host
Write-Host "proj2"
Write-Host "Level 0: " $proj2.GetType()
Write-Host "Level 1: " $proj2.L1.GetType()
Write-Host "Level 2: " $proj2.L1.L1.GetType()
Write-Host "Level 3: " $proj2.L1.L1.L1.GetType()
Write-Host "Level 4: " $proj2.L1.L1.L1.L1.GetType()
Write-Host
Write-Host "proj3"
Write-Host "Level 0: " $proj3.GetType()
Write-Host "Level 1: " $proj3.L1.GetType()
Write-Host "Level 2: " $proj3.L1.L1.GetType()
Write-Host "Level 3: " $proj3.L1.L1.L1.GetType()
Write-Host "Level 4: " $proj3.L1.L1.L1.L1.GetType()
Write-Host
Write-Host "proj4"
Write-Host "Level 0: " $proj4.GetType()
Write-Host "Level 1: " $proj4.L1.GetType()
Write-Host "Level 2: " $proj4.L1.L1.GetType()
Write-Host "Level 3: " $proj4.L1.L1.L1.GetType()
Write-Host "Level 4: " $proj4.L1.L1.L1.L1.GetType()

结果

proj1
Level 0:  System.Collections.Hashtable
Level 1:  System.Collections.Hashtable
You cannot call a method on a null-valued expression.
At D:\Xandorra\SQL\bmsHashTableTest.ps1:25 char:1
+ Write-Host "Level 2: " $proj1.L1.L1.GetType() # Will generate error: You cannot  ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull


proj2
Level 0:  System.Collections.Hashtable
Level 1:  System.Collections.Hashtable
Level 2:  System.Collections.Hashtable
Level 3:  System.Collections.Hashtable
Level 4:  System.Collections.Hashtable

proj3
Level 0:  System.Collections.Hashtable
Level 1:  System.Collections.Hashtable
Level 2:  System.Collections.Hashtable
Level 3:  System.Collections.Hashtable
Level 4:  System.Collections.Hashtable

proj4
Level 0:  System.Collections.Hashtable
Level 1:  System.Collections.Hashtable
Level 2:  System.Collections.Hashtable
Level 3:  System.Collections.Hashtable

我正在使用Powershell 4.0
我的$ PSVersionTable:

Name                           Value                                                               
----                           -----                                                               
PSVersion                      4.0                                                                 
WSManStackVersion              3.0                                                                 
SerializationVersion           1.1.0.1                                                             
CLRVersion                     4.0.30319.34014                                                     
BuildVersion                   6.3.9600.17400                                                      
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0}                                                
PSRemotingProtocolVersion      2.2                                                                 

2 个答案:

答案 0 :(得分:2)

您错过了通过引用而不是按值传递对象这一事实。

您的测试结构会使这些结果蒙上阴影。在其自己的PowerShell实例中运行每个单独的$projX赋值而不运行其他任务,它应该按预期工作。

例如,当你写:

$proj2."$L1" = $emptyHashTable

$proj3       = $emptyHashTable
$proj3."$L1" = @{}

您已将$proj2.L1设为参考$emptyHashTable。因此,您还将$proj3设置为引用$proj2.L1,从而设置为$emptyHashTable。这意味着$proj3.L1 = @{}$proj2.L1.L1 = @{}相同,依此类推。

答案 1 :(得分:0)

这似乎是Powershell v4中的一个错误 当在Powershell v5中运行相同的代码时,不会发生无限深度。