またPowerShellの記事ですが、今回はいつものように長々と書くのではなく、当ブログではすごく久しぶりにメモ程度の記事です。
…と思っていたら、またまた長くなってしまった。
短くまとめられる能力が欲しいですね。
PowerShellでは型を意識しない書き方をできるようになっていますが、ジェネリックスを相手にする場合は型を明示しなければなりません。
そこで、今回はジェネリッククラスとジェネリックメソッドをどのように呼び出せばよいか書きます。
実は私も昔、何回か気にした問題なのですが、その度に忘れるので今回こそメモします。
ジェネリッククラス
まず知っていただきたいのは、型引数をn個持つジェネリッククラスは、PowerShellにおいて本当の名前はその型名に'`n'をくっつけたものであるということです。
つまりは、'System.Collections.Generic.List<T>'とC#で呼ばれているものは、PowerShellでは'System.Collections.Generic.List`1'になって、
'System.Collections.Generic.Dictionary<TKey, TValue>'なら、'System.Collections.Generic.Dictionary`2'となります。
しかし実際のところPowerShellでは、型名を書いたあと型引数を続けて書かなければならないので、そこから推論することが可能です。
つまりは、この数字を後につけることは、あまりないと思います。
静的クラス
まずは静的メンバにアクセスするために、ジェネリッククラス名を書く場合の方法です。
まず型名を[]で囲むわけですが、さっき実験して驚いたことがありまして、
PowerShellの以前のバージョンでは型名を[]で囲んだものを書いてエンターを押しても、別にメソッドを呼んでいるわけでもないのでエラーになっていました。
しかし、先ほどv5.0で実験してみたところ、[]で囲んだ型名だけでも、それはSystem.Typeのインスタンスとして解釈されるようになったようです。
そして[]の後に書く::は、左の[]と結びついている記号じゃなくなり、
左のSystem.Typeが表す型に定義されている静的メンバにアクセスする記号という意味に変わったということです。
これが何を意味するかというと、
$type = '文字列'.GetType()
$type::FullName
こういう変数を介したアクセスが可能になったということです。
さて、本題に戻しますが、要するに話はジェネリッククラスのSystem.Typeをどのように作るかという問題になります。
これは、すごく単純に、まず型名を書いて、そのあと任意で前述の'`n'を付加します。
そして、そのあと[]を付加して、この中に型引数を書きます。
型引数が複数あるなら、','で区切ります。
そして、この時点で型名を書くことができたということになるのですが、ここからSystem.Typeを作るために、全体を[]で囲みます。
よってたとえば、'[System.Collections.Generic.List[string]]'とか、'[System.Collections.Generic.Dictionary[int,string]]'ということになります。
あとは::を書いて普通にメンバ名を書くだけです。