亀岡的プログラマ日記

京都のベッドタウン、亀岡よりだらだらとお送りいたします。

ジェネリック[メソッド/クラス]を動的に呼び出す

意外とやり方がわからないことだなー、と思ってメモしておきます。

やりたいのは、Type型を実行時に渡して、GenericメソッドやGenricクラスを呼び出す、といったものです。メタプロやってると欲しくなるんですよね。

Genericメソッドを呼び出す場合

まずはメソッドから。コードをまず見せましょう。

[TestMethod]
public void CallGenericMethod()
{
    var sut = new Foo();

    var method = typeof (Foo).GetMethod("Bar");
    var constructed = method.MakeGenericMethod(typeof (string));
    constructed.Invoke(sut,null).Is("String");
}
public class Foo
{
    public string Bar<T>()
    {
        return typeof(T).Name;
    }
}

ポイントはMakeGenericMethodですね。MethodInfo型に普通に入っています。まずGetMethodでGenericメソッドを取得した後に、型情報を後から与えてMethodを確定させるような感じですね。

MethodInfoさえできてしまえばあとは通常と一緒です。

参考

Genericクラスを作る場合

続いてクラスです。多分こっちのほうが使う場面は多そうですね。まず、コードから。

[TestMethod]
public void NewGenericClass()
{
    var genericType = typeof (Hoge<>);
    var constructedType = genericType.MakeGenericType(typeof (string));

    var sut = Activator.CreateInstance(constructedType);

    var method = constructedType.GetMethod("Fuga");
    method.Invoke(sut, null).Is("String");
}
public class Hoge<T>
{
    public string Fuga()
    {
        return typeof(T).Name;
    }
}

流れとしては同じような感じですね。まずGenericな型を取得した後に、MakeGenericTypeを使って型情報を与えて確定させます。それからは、Activator.CreatorInstanceの出番ですね。Activatorを使ってしまった都合上、これ以降の呼び出しは普通にReflectionになってしまいますが。

参考