PowerShell は function 内で戻り値をArrayList などのインスタントすると、 PowerShell はパイプライン上にコレクションの各要素を出力するそうです。つまり、コレクションの一つ一つがパイプライン上に渡される変数で返り値を取得するとObject 型の配列になってしまいます。
同様の理由により、要素数が1のコレクションを関数の戻り値とすると、1つのオブジェクトが返り値となります。
パイプライン上で処理する必要がある場合はこの振る舞いでOKでしょうが、 コレクション型を維持したまま 関数の戻り値としたい場合もあると思います。今回はその方法を記載します。
方法は簡単で、 コレクションのインスタンスを返り値とする際に、 コレクションの前に "," カンマを付けるだけです。
動作の違いを確認するために、次の関数を作成しました。
# CollectionFunctionSample.ps1 function Get-List1{ $list = New-Object 'System.Collections.Generic.List`1[System.String]' $list.Add("てすと1") $list.Add("てすと2") ## コレクションクラスは展開されて、Object[] になってしまう。 $list } function Get-List2{ $list = New-Object 'System.Collections.Generic.List`1[System.String]' $list.Add("てすと1") $list.Add("てすと2") ## 返り値の型はList<string> のまま ,$list } function Get-Array1{ $list = New-Object System.Collections.ArrayList [void] $list.Add("てすと1") # 要素が1つのコレクションは展開されて1つのインスタンスになる $list } function Get-Array2{ $list = New-Object System.Collections.ArrayList [void] $list.Add("てすと1") ,$list }
Get-List1 がジェネリック型のコレクションを返り値とする関数です。関数を実行すると結果として、解体されて要素が2つのObject[] になります。
Get-List2 がGet-List1と同様にジェネリック型のコレクションを返り値とする関数です。,$list と指定いるので、関数を実行すると結果として、解体されて要素が2つのObject[] になります。Get-List1, Get-List2 を実行した処理結果は次のようになります。Get-List2 の場合は、Object[] ではなく、 List<string> 型のままであることが確認できます。
PS C:\> . .\CollectionFunctionSample.ps1 PS C:\> $v = Get-List1 PS C:\> $v.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Object[] System.Array PS C:\> $v = Get-List2 PS C:\> $v.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True List`1 System.Object
Get-Array1, 2 は Get-List1,2 と同様ですが、ArrayList型のコレクションを返り値とした例です。実行結果は次のようになります。Get-Array1 の戻り値は単一のString型オブジェクトとなり、Get-Array2の場合はArrayList 型のままであることが確認できます。
PS C:\> . .\CollectionFunctionSample.ps1 PS C:\> $v = Get-Array1 PS C:\> $v.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True String System.Object PS C:\> $v = Get-Array2 PS C:\> $v.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True ArrayList System.Object
今回の説明は以上です。なにげにはまったので、覚書として記載しました。