PowerShell Memo

このサイトはPowerShell(MSH/Monad)奮闘記です

管理人「newpops吉岡洋」が
「PowerShell(旧名:MSH/Monad)」の研究結果を日々綴っていきます。

【お知らせ】
この日記からPowerShellのTipsを抽出し「PowerShell FAQ」として整理しました。


2006-11-21

[]コンソールに選択肢を表示する(2)

ソースコードの解説

コンソールに選択肢を表示する - PowerShell Memoソースコード解説です。

対象ソースコード
 1 #選択肢の作成
 2 $typename = "System.Management.Automation.Host.ChoiceDescription"
 3 $yes = new-object $typename("&Yes","実行する")
 4 $no  = new-object $typename("&No","実行しない")
 5 
 6 #選択肢コレクションの作成
 7 $assembly= $yes.getType().AssemblyQualifiedName
 8 $choice = new-object "System.Collections.ObjectModel.Collection``1[[$assembly]]"
 9 $choice.add($yes)
10 $choice.add($no)
11 
12 #選択プロンプトの表示
13 $answer = $host.ui.PromptForChoice("<実行確認>","実行しますか?",$choice,0)
選択肢(ChoiceDescription)の作成
 1 #選択肢の作成
 2 $typename = "System.Management.Automation.Host.ChoiceDescription"
 3 $yes = new-object $typename("&Yes","実行する")
 4 $no  = new-object $typename("&No","実行しない")
  • 1行目:new-objectで生成する型のフルネームを設定
  • 2行目〜3行目:ChoiceDescriptionオブジェクトを生成しています。
ChoiceDescriptionのコレクション(Generics)を生成する

13行目で実行するPromptForChoiceメソッドの詳細を見てみます。

PSHostUserInterface.PromptForChoice Method (String, String, Collection(ChoiceDescription), Int32) (System.Management.Automation.Host)

上記ページによると、第3引数は「ChoiceDescription」オブジェクトのコレクションです。

 6 #選択肢コレクションの作成
 7 $assembly= $yes.getType().AssemblyQualifiedName
 8 $choice = new-object "System.Collections.ObjectModel.Collection``1[[$assembly]]"
 9 $choice.add($yes)
10 $choice.add($no)
  • 7行目〜10行目はChoiceDescriptionオブジェクトのコレクション(Generic)を生成しようとしています。
  • 7行目:ChoiceDescriptionのアセンブリ完全修飾名を取得
  • 8行目:ChoiceDescriptionのGenericコレクションを生成
  • 9行目〜10行目:ChoiceDescriptionオブジェクトをコレクションに格納
なぜ、Genericsコレクションを生成しているのか?

PromptForChoiceメソッドに第3引数に不適切な型の変数を渡すと・・・

$host.ui.PromptForChoice("","",("",""),0)

※上記はString配列(実際にはObject配列が)を渡しています。

この型↓に変換できないとエラーが出ます。

"System.Collections.ObjectModel.Collection`1
 [System.Management.Automation.Host.ChoiceDescription]"

「System.Collections.ObjectModel.Collection」はGenericクラスですから、

Genericコレクションが必要だと判断しました。


しかし、調べてみると、

7行目〜10行目までは以下のように書いてもOKでした。(^^;

$choice = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)

なぜ、Genericのコレクションを待ち受けている所に、通常の配列を渡してもOKなのでしょうか?

#.NETの仕様?PowerShellの仕様?


PromptForChoiceの実行
12 #選択プロンプトの表示
13 $answer = $host.ui.PromptForChoice("<実行確認>","実行しますか?",$choice,0)
  • 13行目:PromptForChoiceを実行して選択肢を表示させています。
    • 第1引数:選択プロンプトのタイトル
    • 第2引数:選択プロンプトに表示するメッセージ<
    • 第3引数:選択肢のコレクション
    • 第4引数デフォルトの選択肢番号。0が1番目の選択肢です。
補足

Genericコレクションを生成しなくても良いことが分かったので、

通常のChoiceDescriptionコレクションを利用したコードを載せておきます。

#こっちの方が楽だったりします。(^^;

#選択肢の作成
$typename = "System.Management.Automation.Host.ChoiceDescription"
$yes = new-object $typename("&Yes","実行する")
$no  = new-object $typename("&No","実行しない")

#選択肢コレクションの作成
$choice = [System.Management.Automation.Host.ChoiceDescription[]]($yes,$no)

#選択プロンプトの表示
$answer = $host.ui.PromptForChoice("<実行確認>","実行しますか?",$choice,0)