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
抱歉,如果

这个查询似乎混淆了,但我发现很难描述这个问题。

我该如何解决这个问题?

奇怪的是,这似乎有效...

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

我得到了预期的输出

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

在这两种情况下,它们看起来是相同的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

稍微挖掘一下,一个包含一个通用列表(List'1),另一个包含stringsstring[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

谢谢!!超级成功了。

我确实必须对打印代码的内部循环进行更改,将"$ge in $g"替换为"$ge in $g.item(0)",因为列表$group声明中的更改引入了另一个级别的间接性。

完整的解决方案是:

$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
  }
}

最新更新