PowerShellで以下のコードを実行すると結果は何になるでしょう?
PS>(1,2,3).GetType()
結果は配列(System.Array)で具体的にはObject[]ということでオブジェクト型の配列となります。
実際配列の要素は数値を設定してあるので整数型のInt型になるかと思いましたが、大概のオブジェクトの祖であるObjectの配列となっています。数値型もObjectから派生しているのでObject[]の配列の要素となることが出来ます。
配列を?(Where-Object)で要素を絞り込んでみます。
PS>(1,2,3) | ? { $_ -lt 3}
1
2
3より小さな値で絞り込むと1と2が結果として戻ります。
さてこの結果の型は何になるでしょう?
PS>((1,2,3) | ? { $_ -lt 3}).GetType()
先ほどと同様にObject型の配列が戻ります。
次に絞り込み条件を2より小さな値で実行してみます。
PS>(1,2,3) | ? { $_ -lt 2}
1
結果1が戻ります。この型を確認してみます。
PS>((1,2,3) | ? { $_ -lt 2}).GetType()
先ほどと異なりSystem.ValueTypeが戻ります。配列(System.Array)ではなく値型(System.ValueType)です。
具体的にはInt32ですので整数値になります。先ほどがこちらがObject型でした。
さらに絞り込み条件を変えてみます。
PS>(1,2,3) | ? { $_ -lt 1}
1より小さな値は存在しないので何も返ってこないようです。
では型を確認しようかと思いますが、何も返ってこないとことで$Nullと比較してみます。
PS>((1,2,3) | ? { $_ -lt 1}) -eq $Null
True
まとめると、パイプラインの戻り値が複数ある場合、配列(System.Array)が返り、1件の場合、値型(System.ValueType)が返り、0件(無い)の場合$Nullが返ります。
型を意識することなくプログラミング出来るのがPowerShellの良さですが、逆にいうと、「この処理でこの変数はこの型であろう」と期待すると裏切られるかもしれません。
ちなみに同じ.NetFrameworkのオブジェクトを扱えるC#のLINQとPowerShellのパイプラインを同時学習すると、似ているようで異なりますので、どうしてこのように作ったか想像してみるのも面白いです。
コメント