HIDORI on The Web

マネージコードしか書きたくない

PowerShell でジェネリックメソッドを呼び出す

with one comment

PowerShell の長所の一つとして「.NET Framework との親和性が高い」ことが挙げられるわけですが、いかんせんジェネリックメソッドの呼び出しはちょとシンドイ。

というわけで、ジェネリックメソッド呼び出しのメンドクサさを隠蔽すべく

Param(
    [Parameter(Mandatory=$True, HelpMessage="ジェネリックメソッドを公開する型を指定します。")]
	[ValidateNotNull()]
	[Type] $Type,

    [Parameter(Mandatory=$True, HelpMessage="ジェネリックメソッドの名前を指定します。")]
	[ValidateNotNullOrEmpty()]
	[String] $MethodName,

    [Parameter(Mandatory=$True, HelpMessage="ジェネリック型パラメータに与える Type 型の配列を指定します。")]
	[ValidateNotNullOrEmpty()]
	[Type[]] $GenericArgumentTypes,

    [Parameter(HelpMessage="ジェネリックメソッド呼び出しの対象となるオブジェクトインスタンスを指定します。")]
	[Object] $Object = $Null,

	[Parameter(HelpMessage="ジェネリックメソッド呼び出しの引数となる Object 型の配列を指定します。")]
	[ValidateNotNull()]
	[Object[]] $ArgumentList = @())

Trap { break }

$MethodInfo = $Type.GetMethods() |
    Where-Object {$_.Name -eq $MethodName} |
    Where-Object {$_.IsGenericMethod} |
    Where-Object {$MethodInfo.GetGenericArguments().Length -eq $GenericArgumentTypes.Length} |
	Select-Object -First 1

$GenericMethodInfo = $MethodInfo.MakeGenericMethod($GenericArgumentTypes)

$GenericMethodInfo.Invoke($Object, $ArgumentList)

なんてスクリプトを書いてみた。

使い方は

Invoke-GenericMethod.ps1 -Type Linq.Enumerable -MethodName Repeat -GenericArgumentTypes Int32 -ArgumentList @(9,4)

みたいな感じ。

これは、C# の

Enumerable.Repeat<int>(9, 4);

に相当。

ちょっと引数が多いけど、汎用的に仕上げたかったのでこんなモンでしょう。

必要に応じて

Function EnumerableRepeat([Int32] $Element, [Int32] $Count)
{
    Invoke-GenericMethod.ps1 -Type Linq.Enumerable -MethodName Repeat  -GenericArgumentTypes Int32 -ArgumentList @(9,4)
}

みたいなラッパ関数を書くってのも手。

Written by Hiroaki SHIBUKI

1月 17th, 2011 at 12:08 am

One Response to 'PowerShell でジェネリックメソッドを呼び出す'

Subscribe to comments with RSS or TrackBack to 'PowerShell でジェネリックメソッドを呼び出す'.

  1. こんばんは。

    http://social.technet.microsoft.com/Forums/ja-JP/powershellja/thread/f1ca0706-df53-4cc7-8136-ac2f897641bd
    で紹介があったので拝見させていただきました。
    このスレッドですでに書きましたが、コード中の

    Where-Object {$MethodInfo.GetGenericArguments().Length -eq $GenericArgumentTypes.Length} |

    Where-Object {$_.GetGenericArguments().Length -eq $GenericArgumentTypes.Length} |

    が正しいと思われます。
    以上、ご報告まで。

    牟田口大介

    25 3月 11 at 11:50 PM

Leave a Reply