2016-09-29 4 views
1

Wenn ich eine $ emptyHashTable-Variable verwende, um eine leere Hashtabelle zu erstellen, scheint es eine endlose Tiefenhashtabelle zu erzeugen. Kann nicht herausfinden warum.
Wenn ich @ {} verwende, funktioniert es korrekt.HashTable mit endloser Tiefe. Warum? Wie vermeide ich?

Codebeispiel

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() 

Outcome

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 

Ich verwende Powershell 4.0
My $ 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                 

Antwort

0

Dies scheint ein Fehler in Powershell v4 zu sein.
Wenn derselbe Code in Powershell v5 ausgeführt wird, tritt die Endlostiefe nicht auf.

2

Sie verpassen die Tatsache, dass Objekte übergeben werden durch Referenz, nicht nach Wert.

Es ist die Struktur Ihrer Tests, die diese Ergebnisse trübt. Führen Sie jede einzelne $projX Zuweisung in einer eigenen Powershell-Instanz aus, ohne die anderen auszuführen, und sie sollte wie erwartet funktionieren.

Zum Beispiel, wenn Sie schreiben:

$proj2."$L1" = $emptyHashTable 

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

Sie $proj2.L1 sein, um einen Referenz-$emptyHashTable festgelegt haben. Als solche setzen Sie auch $proj3 als Referenz bis $proj2.L1 und damit $emptyHashTable. Das bedeutet, dass $proj3.L1 = @{} dasselbe ist wie $proj2.L1.L1 = @{} und so weiter.

+0

Ich bin mir nicht sicher, ob das stimmt. Wenn ich $ proj2.L1 als Verweis auf $ emptyHashTable einstelle, könnte man sagen, dass $ proj2.L1 ein Zeiger auf $ emptyHashTable ist. Ein Zeiger ist in eine Richtung. Wenn ich mich also nicht irre, ist $ emptyHashTable kein Verweis auf $ proj2.L1. Wenn ich dann $ emptyHashTable $ proj3 zuweise, dann ist $ proj3 ein Zeiger auf $ emptyHashTable. Ich sehe nicht, wie das eine Referenz (Zeiger) zu $ ​​proj2.L1 werden kann. –

Verwandte Themen