#はじめに
C#でReflectionを使ったことがありますか?
Reflectionを使うことで今まではできなかったような処理を書くことができます
その一つとしてgenericのクラスの呼び出し方法を今回はご紹介します。
#Typeを取得する
##普通に取得する方法
呼び出したいインスタンス.GetType();
Type.GetType("genericの型`引数の型の数[[型],[型].....]"):
typeof(genericの型<型>);
注意点としては文字列で<>ではなく[]にする必要があり、ジェネリックの数が`の後に必要です
通常ライブラリを使うだけならなにも問題はありません
しかし、動的コード生成する場合や動的にDLLを読み込むときに使用する場合は問題が発生します。
##動的な読み込みの際に取得する方法
動的にDLL等を読み込むときは上記の方法ではできません
なので別な方法でする必要があります。
これは他のクラスを取得する方法と同じだと思っていました
しかしそれではダメだったのでご紹介します
###ダメだった方法
呼び出したいアセンブリ型のインスタンス.GetType("genericの型`引数の型の数[[型],[型].....]"):
この方法では他の型を読み込んでくれないためだめでした。
###つまずいた方法
調べているとMakeGenericTypeメソッドでgenericの型の引数を任意に決めれると書いてあったのでやってみました。
Type t = 呼び出したいアセンブリ型のインスタンス.GetType("genericの型`引数の型の数"):
//ジェネリック自体の型を取得
t.MakeGenericType(指定したい型のType);
しかし問題がこれを書いてブレークポイントで確認してみましたが
tの中は変わっていませんでした。
実はMakeGenericTypeは適応したgeneric型のtypeを新しく作るメソッドでした
つまり...
###正しい方法
Type t1 = 呼び出したいアセンブリ型のインスタンス.GetType("genericの型`引数の型の数"):
//ジェネリック自体の型を取得
Type t2 = t.MakeGenericType(指定したい型のType);
このようにすることで動的に読み込んだgeneric型のTypeを取得することができます。
MakeGenericTypeメソッドは新しく作ったType型を戻り値として出すメソッドですので
ちゃんと代入しないとだめですよね
#まとめ
まとめとしてはちゃんとメソッドの仕様を調べて使うことにしましょう。
でないと、私みたいに痛い目を見ます。
皆様お気を付けて
この辺りで失礼します。