如何轉換為 ArrayList,在 param 塊中預設數據,並返回為 ArrayList?
由於我需要能夠從數組中添加和刪除項目,因此我需要將其轉換為
ArrayList
與更常見的選項(、、、[string[]]
)[Array]
相反的值$Var=@()
。我還需要用數據對其進行預設,但函式的呼叫者需要能夠根據需要更改預設。塊中的預設Param()
是必需的,因為另一個實體正在尋找預設數據。我嘗試了幾種變體,但這是最有意義的一種:Function Test-Me{ Param ( $Properties = [System.Collection.ArrayList]@( "red", "blue", "green") ) $Properties.GetType() $Properties.Add("orange") }
上面的內容很好,只是一旦有人呼叫
Test-Me -Properties "Purple","Yellow","Black"
該$Properties
變數就成為標準Array
類型(因此添加和刪除方法不起作用)。我嘗試了更改我聲明預設值的方式的方法。似乎預填充的行為是將類型轉換為正常數組。我認為這是因為我使用
@()
的是預設,所以我也嘗試()
過。這也不起作用:
Param ( [System.Collection.ArrayList] $Properties = @("red", "blue", "green") )
我有一個解決方法可以轉換 Param 塊之外的類型,它看起來像這樣:
Function Test-Me{ Param ( [String[]] $Properties = @("red", "blue", "green") ) if("Orange" -notin $Properties){ [System.Collections.ArrayList]$Properties = $Properties $Properties.Add("orange") } }
我覺得我應該能夠
ArrayList
在 param 塊中轉換為 an 並用數據預設它,並以相同的 datatype 返回,但我無法弄清楚。如果有人這樣做,或者找到了為什麼它不起作用的文件,請回答。
顯式參數類型轉換
您發布的第二個範例(顯式轉換參數變數)是正確的方法:
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
輸出類型
令我驚訝的一件事是,即使使用該
[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
更新(使用簡單的解決方法)
正如對您的Connect 錯誤送出的評論中所展示的那樣,PowerShell 故意列舉任何可列舉輸出的項目,以便為管道提供一致的行為(從評論者 Derp McDerp 在 Connect 上竊取的偽 C#):
if (returned_value is IEnumerable) { foreach (r in returned_value) { yield r; } } else { yield returned_value; }
然後訣竅是將集合包裝在一個單項數組中,導致 PowerShell 將其作為單個項進行管道傳輸(注意
,
before$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 }
現在,我們得到了正確類型的輸出:
PS C:\> (Test-Me).GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True ArrayList System.Object