C#與CLR學習筆記(8)—— 通過反射調用泛型方法

1 調用非泛型方法

通過反射創建一個對象,然後調用其方法的一般過程爲:

  1. 加載程序集,並獲取類型
  2. 通過類型,實例化一個類型對象(調用靜態方法則不必實例化)
  3. 根據名稱、方法簽名、可訪問性等約束,獲取要調用的方法
  4. 通過 Invoke 方法,傳入實際參數,進行調用。

案例:

public class ReflectionTest
{
    // 無參構造函數
    public ReflectionTest(){}
    
    public void Show(string name, int id)
    {
        Console.WriteLine("調用了Show(string, int)");
    }
    // 私有方法
    private void Show2()
    {
        Console.WriteLine("調用了私有Show2()");
    }
}
//下面通過反射調用方法
var assembly = Assembly.Load("XX");//XX是ReflectionTest所在的程序集名稱
var type = assembly.GetType("XX.ReflectionTest");
object oReflTest = Activator.CreateInstance(type);//會調用(無參)構造函數
MethodInfo mi = type.GetMethod("Show", new Type[] { typeof(string), typeof(int) });
mi.Invoke(oReflTest, new object[] { "123", 123 });
//調用私有方法
MethodInfo mi = type.GetMethod("Show2", BindingFlags.NonPublic|BindingFlags.Instance);
mi.Invoke(oReflTest, null);

2 調用泛型類的泛型方法

對於泛型類的泛型方法,過程與非泛型類的非泛型方法是一樣的,只不過,泛型類的實例化方式不太一樣,泛型方法的調用也不太一樣。

由於未指定泛型類型實參(T)的泛型類型是一種 開放類型,開放類型是不允許進行實例化的,因此,需首先指定 T 的類型實參(例如 int, string 等實際類型),將其轉爲 封閉類型 後才能進行實例化。泛型方法也是類似,需指定類型實參才能傳遞匹配的實際參數,進行調用。
案例:

public class GenericClass<T>
{
    public void Show<W, X>(T t, W w, X x)
    {
        Console.WriteLine($"t.type={t.GetType().Name},w.type={w.GetType().Name},x.type=x.GetType().Name}");
    }
}
//通過反射調用
assembly = Assembly.Load("XX");//XX是GenericClass<T>所在的程序集名稱
Type typeOpen = assembly.GetType("XX.GenericClass`1");//注意泛型類型名稱
//通過MakeGenericType()方法創建泛型類型
Type typeClosed = typeOpen.MakeGenericType(new Type[] { typeof(int) });
object oGenRefl = Activator.CreateInstance(typeClosed);

MethodInfo mi = typeClosed.GetMethod("Show");//沒有重載時可以不指定方法參數類型
MethodInfo mi2 = mi.MakeGenericMethod(new Type[] { typeof(string), typeof(DateTime) });
mi2.Invoke(oGenRefl, new object[] { 12, "12", DateTime.Now });//注意泛型類型的匹配
//輸出結果如下:
t.type=Int32,w.type=String,x.type=DateTime
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章