2016-09-29 22 views
1

當我使用$ emptyHashTable變量創建一個空的散列表時,它似乎會生成一個無窮深度的散列表。無法弄清楚原因。
當我使用@ {}時,它工作正確。具有無窮深度的HashTable。爲什麼?如何避免?

代碼示例

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                 

回答

0

這似乎是Powershell v4中的一個錯誤。
當在Powershell v5中運行相同的代碼時,無限深度不會發生。

2

你缺少對象傳遞的事實作爲參考,而不是價值。

這是你的測試結構混淆這些結果。在其自己的PowerShell實例中運行每個$projX作業,而不運行其他作業,並且應該按預期工作。

例如,當你寫:

$proj2."$L1" = $emptyHashTable 

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

你設置$proj2.L1是一個參考$emptyHashTable。因此,您還將$proj3設置爲參考$proj2.L1,因此設置爲$emptyHashTable。這意味着$proj3.L1 = @{}$proj2.L1.L1 = @{}相同,依此類推。

+0

我不確定這是否正確。當我將$ proj2.L1設置爲$ emptyHashTable的引用時,可以說$ proj2.L1是一個指向$ emptyHashTable的指針。指針是單向的。所以,如果我沒有弄錯,$ emptyHashTable不是返回到$ proj2.L1的引用。當我將$ emptyHashTable分配給$ proj3時,$ proj3是一個指向$ emptyHashTable的指針。我看不出如何成爲一個參考(指針)到$ proj2.L1。 –

相關問題