2016-10-01 60 views
1

我想通過使用泛型參數類型的子類型的反射來調用泛型方法。這裏的情況:調用泛型參數類型的子類型的通用方法

public abstract class MyClass<T> where T : class 
{ 
} 

public static class Caller 
{ 
    public static void Do<T>(MyClass<T> param1, string param2 = null) where T : class 
    { 

    } 
} 

public class ConcreteClass : MyClass<string> 
{ 

} 

然而,當我嘗試這樣做:

ConcreteClass instance = Activator.CreateInstance(typeof(ConcreteClass)); 
MethodInfo methodInfo = typeof(Caller).GetMethod("Do"); 
methodInfo = methodInfo.MakeGenericMethod(typeof(ConcreteClass)); 
methodInfo.Invoke(null, new object[] { instance, Type.Missing }); 

我基本上得到一個例外,他說:

無法將類型「具體類爲鍵入「MyClass` [ConcreteClass]'

異常消息非常清晰,howe我似乎並沒有找到自己能夠實現的目標。

編輯:

的編譯時間對相當於什麼,我想實現的是:

Caller.Do(new ConcreteClass()); 

哪個編譯罰款。

+0

不知道是否它只是從例子,但確實'MyClass的'符合你的'MyClass的其中T:class'要求? –

+0

@ Dan-Cook非常感謝您對這個問題的興趣,是的,它通常會這樣做(字符串約束僅用於示例) – reddy

回答

1

ConcreteClass延伸MyClass<string>所以你需要提供typeof(string)MakeGenericMethod

ConcreteClass instance = (ConcreteClass)Activator.CreateInstance(typeof(ConcreteClass)); 
MethodInfo methodInfo = typeof(Caller).GetMethod("Do"); 
methodInfo = methodInfo.MakeGenericMethod(typeof(string)); 
methodInfo.Invoke(null, new object[] { instance, Type.Missing }); 
0

您的基於反射的代碼正試圖運行時相當於Caller.Do<ConcreteClass>(instance, Type.Missing)

這是無效的。方法Do<>需要匹配類型 - 對於Do<ConcreteClass>,您需要一個是或是MyClass<ConcreteClass>的子類的實例。

ConcreteClassMyClass<string>的子類。爲此,您需要撥打Do<string>(instance)或整體Caller.Do<string>(instance, Type.Missing)

+0

感謝您的幫助,但有些不正確我害怕。做Caller.Do(新的ConcreteClass())被編譯器完全接受,因此應該有一種方法使用反射來實現相同的方法。 – reddy

+0

這是因爲編譯器可以正確推斷出正確的類型。但是,使用反射代碼,您明確提供了無效的類型組合。 – yaakov

相關問題