之前做過一次,呼叫泛型方法,但型態在寫的時候還沒決定,
或是這個型態是個變數,還未知的,要做成下面這樣
public GenericMethod(object obj);
Type type = someobject.GetType();
GenericMethod(someobject);
想當然程式寫成這個樣子是不可行的。
所以才寫這個筆記…
public class Checker
{
public T Check(T data)
{
// ...........
}
}
假設有個泛型方法長這樣。
第一次寫的時候用的是System.CodeDom.compiler這個命名空間的東西,
也就是把程式碼當成寫成字串,在執行時期再編譯,
這樣在寫那個字串的時候我就可以程式執行的時候再代入Check,Check,Check等等…
然後執行時編譯成dll,後面程式再動態呼叫dll,再呼叫這個函式。
聽起來就是很麻煩,程式也不好維護…
今天又再一次需要這樣做這樣的東西,
這次有看到好很多的方法,用System.Reflection
Type type = someThing.GetType();
MethodInfo method = typeof(Checker).GetMethod("Check");
var checker = new Checker();
var retData = method.MakeGenericMethod(type).Invoke(checker, new object[]{ something });
這樣做就可以了,如果這個是static function,Invoke的第一個參數就不用帶實體進去,用null就可以,這裡比較麻煩的地方有兩點
- 回傳值都會是object,但是是可以成功轉型的,用is運算子來判斷也會是對的。
- 如果這個方法是有同名異式的(overwrite),用GetMethod就會出錯(找到不只一個),必須用GetMethods再去下條件做篩選。
Person someone = new Person();
var checker = new Checker();
// 基本大家都知道的方法…
var newPerson = checker.check(someone);
// 新的做法
var type = someone.GetType();
var retData = typeof(Checker).GetMethod("Check").
MakeGenericMethod(type).
Invoke(checker, new object[]{ someone });
var newPerson = retData as Person;
沒有留言:
張貼留言