「オブジェクト配列」と「Genericコレクション」の関係
コンソールに選択肢を表示する(2) - PowerShell Memoで以下の疑問がわきました。
なぜ、Genericのコレクションを待ち受けている所に、通常の配列を渡してもOKなのでしょうか?
そこで、オブジェクト配列とGenericコレクションの関係について検証した所、
PowerShellではオブジェクト配列とGenericコレクションは相互にキャスト可能という事が分かりました。
驚きです。(少なくともVB.NETではキャストできませんでした。)
以下は検証コードです。
検証コード
#選択肢オブジェクトの作成
$choiceTypename = "System.Management.Automation.Host.ChoiceDescription"
$yes = new-object $choiceTypename("&Yes","実行する")
$no = new-object $choiceTypename("&No","実行しない")
#「オブジェクト配列」の作成
$choiceArray = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)
#「Genericコレクション」の作成
$assembly= $yes.getType().AssemblyQualifiedName
$genericTypename = "System.Collections.ObjectModel.Collection``1[[$assembly]]"
$choiceGeneric = new-object $genericTypename
#【1】「オブジェクト配列」=「Genericコレクション」か?
$choiceArray -is $genericTypename
#【2】「Genericコレクション」=「オブジェクト配列」か?
$choiceGeneric -is `
[System.Management.Automation.Host.ChoiceDescription[]]
#【3】オブジェクト配列をGenericコレクションにキャスト可能か?
$choiceArrayCast = $choiceArray -as $genericTypename
#【4】キャスト後の型はGenericコレクションか?
$choiceArrayCast -is $genericTypename
#【5】オブジェクト配列をGenericコレクションにキャスト可能か?
$choiceGenericCast = $choiceGeneric -as `
[System.Management.Automation.Host.ChoiceDescription[]]
#【6】キャスト後の型はオブジェクト配列か?
$choiceGenericCast -is `
[System.Management.Automation.Host.ChoiceDescription[]]
検証結果
型の比較
PS C:\> #【1】「オブジェクト配列」=「Genericコレクション」か? PS C:\> $choiceArray -is $genericTypename False PS C:\> PS C:\> #【2】「Genericコレクション」=「オブジェクト配列」か? PS C:\> $choiceGeneric -is ` >> [System.Management.Automation.Host.ChoiceDescription[]] >> False
一応確認です。
「オブジェクト配列」と「Genericコレクション」は異なる型ですね。
「オブジェクト配列」→「Genericコレクション」へのキャスト
PS C:\> #【3】オブジェクト配列をGenericコレクションにキャスト可能か? PS C:\> $choiceArrayCast = $choiceArray -as $genericTypename PS C:\> PS C:\> #【4】キャスト後の型はGenericコレクションか? PS C:\> $choiceArrayCast -is $genericTypename True
「オブジェクト配列」は「Genericコレクション」へキャスト可能であることが分かります。
「Genericコレクション」→「オブジェクト配列」へのキャスト
PS C:\> #【5】オブジェクト配列をGenericコレクションにキャスト可能か? PS C:\> $choiceGenericCast = $choiceGeneric -as ` >> [System.Management.Automation.Host.ChoiceDescription[]] >> PS C:\> #【6】キャスト後の型はオブジェクト配列か? PS C:\> $choiceGenericCast -is ` >> [System.Management.Automation.Host.ChoiceDescription[]] >> True
「Genericコレクション」は「オブジェクト配列」へキャスト可能であることが分かります。
結論
PowerShellでは「オブジェクト配列」と「Genericコレクション」は相互にキャスト可能です。
Genericのコレクションを引数に取るメソッドに、オブジェクト配列を渡してもOKなのは、
おそらく、PowerShellが内部で型をキャストしてくれているのでしょう。