鷲ノ巣

C# とか PowerShell とか。当ブログの記事は(特に公開直後は)頻繁に改定される場合があることをご了承ください。

PowerShell コマンドを C# で書くときに便利な拡張メソッド

たまにはね、会社ブログの報告ばかりじゃなくて、自前の記事も書きましょうね。
リハビリというわけじゃないですが、軽めの記事をひとつ。

よくある話

PowerShell Cmdlet で、あるパラメーターが指定されているかどうかで処理を分けることはよくあります。
スクリプトだと $PSBoundParameters を見て判断するんですが、C# では PSCmdlet.MyInvocation.BoundParameters を使って実現できます。
ただ、この辞書にアクセスするのに、パラメーター名を文字列で指定しなければいけないというのはよろしくありません。
基本的に、リテラルは書いたら負けです。許容できても一度までです。

というわけで、こんな拡張メソッドを作っておくと、タイプミスもなくせて大変便利です。
PowerShell Cmdlet では、パラメーター名はメンバー名ですからね。

gistc7a626c3d2c33100c021

こんなふうに使います。

this.HasParameter(x => x.Name)

GetMemberName メソッドは、あらゆるクラスにとって有用なメソッドではありますが、あらゆるクラスを汚染するメソッドでもあります。
このサンプルでは internal にしているので影響はアセンブリ内に限られますが、より限定したい場合は、

where TType : PSCmdlet

という制限をかけてもよいでしょう。
その辺りはお好みでどうぞ。

最近の方法

タイプセーフにメンバー名を取得するのに Expression を使うのは常套手段ではあるのですが、いささか大仰な気もします。
Expression としてはコンパイルが通ってしまうようなコードでも、GetMemberName 的には不正で実行時エラーになるということもあり得ます。
よりシンプルで安全な方法はないものでしょうか。

ところで、我が家もやっと Windows10 と Visual Studio 2015 を導入できました。
というわけで、C# 6.0 を使ったコードを思う存分書くことができます。

つまり、アレが使えるわけです。

this.HasParameter(nameof(this.Name))

(`・ω・)b