如何转换为ArrayList,在param块中预置数据,并返回ArrayList?

因为我需要能够添加和删除数组中的项目,我需要把它转换为ArrayList ,而不是更常见的选项( [string[]][Array]$Var=@() )。 我也需要用数据预设它,但function的调用者需要能够根据需要更改预设。 Param()块中的预设是必需的,因为另一个实体正在查找预设数据。 我已经尝试了几个变化,但是这是最有意义的:

 Function Test-Me{ Param ( $Properties = [System.Collection.ArrayList]@( "red", "blue", "green") ) $Properties.GetType() $Properties.Add("orange") } 

除了只要有人调用Test-Me -Properties "Purple","Yellow","Black"$Propertiesvariables就成为一个标准的Arraytypes(其中add和remove方法不起作用),上面的内容就非常棒了。

我试着改变我如何声明预设值的方法。 看来,预填充的行为是将types转换为常规数组。 我想这是因为我用@()与预设,所以我试过()以及。

这也不起作用:

 Param ( [System.Collection.ArrayList] $Properties = @("red", "blue", "green") ) 

我有一个解决scheme转换Param块外的types,它看起来像这样:

 Function Test-Me{ Param ( [String[]] $Properties = @("red", "blue", "green") ) if("Orange" -notin $Properties){ [System.Collections.ArrayList]$Properties = $Properties $Properties.Add("orange") } } 

我觉得我应该能够在param块中作为一个ArrayList进行转换,并将其预置为数据, 并返回为相同的数据types ,但我无法弄清楚。 如果有人这样做,或find文件为什么不起作用,请回答。

显式参数types转换

你发布的第二个例子(明确地转换参数variables) 正确的方法:

 Function Test-Me { Param( [System.Collections.ArrayList] $Properties = @("red","blue","green") ) Write-Host $Properties.GetType().FullName if("Orange" -notin $Properties){ [void]$Properties.Add("orange") } $Properties } 

导致:

 PS C:\> Test-Me System.Collections.ArrayList red blue green orange PS C:\> Test-Me -Properties "one","two","three" System.Collections.ArrayList one two three orange 

输出types

有一件事让我感到惊讶,即使使用[OutputType]属性,函数也会输出一个常规数组(这可能实际上是一个错误的预期行为,请参阅下面的更新):

 Function Test-Me { [OutputType([System.Collections.ArrayList])] Param( [System.Collections.ArrayList] $Properties = @("red","blue","green") ) if("Orange" -notin $Properties){ [void]$Properties.Add("orange") } $Properties } 

仍然导致返回一个常规的对象数组:

 PS C:\> (Test-Me).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array 

更新(简单的解决方法)

正如您在连接错误提交的评论中所展示的那样,PowerShell故意枚举任何可枚举输出的项目,以便为pipe道提供一致的行为(伪C#在Connect上从评论者Derp McDerp中被盗):

 if (returned_value is IEnumerable) { foreach (r in returned_value) { yield r; } } else { yield returned_value; } 

然后把这个集合包装在一个单一的数组中,导致PowerShell将它作为一个单独的项目(请注意,$Properties之前):

 Function Test-Me { [OutputType([System.Collections.ArrayList])] Param( [System.Collections.ArrayList] $Properties = @("red","blue","green") ) if("Orange" -notin $Properties){ [void]$Properties.Add("orange") } ,$Properties } 

现在,我们得到一个正确types的输出:

 PS C:\> (Test-Me).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True ArrayList System.Object