2017-10-25 1 views
1


各エントリがそれ自身(文字列の)リストであるリストがあります。powershellリストのリスト:エントリの初期化は値ではなくアドレスで行われる

しかし、リストをリストのリストに割り当てると、割り当ては値ではなく参照によって実行されるようです。つまり、基本となるリストが変更された場合、「リストのリスト」も変更されます。

以下のコードは、問題を示しています

$work=New-Object "System.Collections.Generic.List[String]" 
$group=New-Object "System.Collections.Generic.List[System.Collections.Generic.List[String]]" 

$work.Add("One") 
$work.Add("Two") 
$group.Add($work) 
write-host "-->First Add" 
foreach ($g in $group) { 
    write-host "--Entry" 
    foreach ($ge in $g) { 
    write-host $ge 
    } 
} 

$work.Clear() 
$work.Add("OneOne") 
$work.Add("TwoTwo") 
$group.Add($work) 

write-host "-->Second Add" 
foreach ($g in $group) { 
    write-host "--Entry" 
    foreach ($ge in $g) { 
    write-host $ge 
    } 
} 

私はこの出力を得る:

-->First Add 
--Entry 
One 
Two 
-->Second Add 
--Entry 
OneOne 
TwoTwo 
--Entry 
OneOne 
TwoTwo 

私はこの期待している:このクエリが混ざっているようだ場合

-->First Add 
--Entry 
One 
Two 
-->Second Add 
--Entry 
One 
Two 
--Entry 
OneOne 
TwoTwo 

謝罪を私はこの問題を説明することが難しいと思う。

どうすればこの問題を解決できますか?

答えて

0

奇妙なことに、これが動作しているように見えます...

$work = New-Object System.Collections.Generic.List[String] 
$group = New-Object System.Collections.Generic.List[[String[]]] 

私は、彼らが同じtype

PS C:\> $group=New-Object "System.Collections.Generic.List[System.Collections.Generic.List[String]]" 
PS C:\> $group.gettype() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  List`1         System.Object 


PS C:\> $group2=New-Object "System.Collections.Generic.List[[String[]]]" 
PS C:\> $group2.gettype() 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  List`1         System.Object 

掘削であることを見てどちらの場合も予想される出力

-->First Add 
--Entry 
One 
Two 
-->Second Add 
--Entry 
One 
Two 
--Entry 
OneOne 
TwoTwo 

を取得少し、1つは一般的なリスト(List'1)を含み、もう1つはの([string[]]

PS C:\> $group.gettype() | select -ExpandProperty GenericTypeArguments 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  List`1         System.Object 


PS C:\> $group2.gettype() | select -ExpandProperty GenericTypeArguments 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  String[]         System.Array 
0

感謝! スーパーはそのトリックをしました。

リスト$グループ宣言の変更が導入されたので、 "$ g in $ g"を "$ g.item(0)の$ ge"に置き換えて、印刷コードの内側ループを変更する必要がありましたインダイレクションの別のレベル

完全なソリューションは、次のとおりです。

$work=New-Object "System.Collections.Generic.List[String]" 
$group=New-Object "System.Collections.Generic.List[System.Collections.Generic.List[String[]]]" 

$work.Add("One") 
$work.Add("Two") 
$group.Add($work) 
write-host "-->First Add" 
foreach ($g in $group) { 
    write-host "--Entry" 
    $i=0 
    foreach ($ge in $g.item(0)) { 
    write-host "$i`:$ge" 
    ++$i 
    } 
} 

$work.Clear() 
$work.Add("OneOne") 
$work.Add("TwoTwo") 
$group.Add($work) 

write-host "-->Second Add" 
foreach ($g in $group) { 
    write-host "--Entry" 
    $i=0 
    foreach ($ge in $g.item(0)) { 
    write-host "$i`:$ge" 
    ++$i 
    } 
} 
関連する問題