2012-01-27 45 views
4

我有以下的例子類:反思 - 泛型列表調用方法,結果

public class MyClass<T> 
{ 
    public IList<T> GetAll() 
    { 
     return null; // of course, something more meaningfull happens here... 
    } 
} 

而且我想調用GetAll與反思:

Type myClassType = typeof(MyClass<>); 
Type[] typeArgs = { typeof(object) }; 
Type constructed = myClassType.MakeGenericType(typeArgs); 
var myClassInstance = Activator.CreateInstance(constructed); 

MethodInfo getAllMethod = myClassType.GetMethod("GetAll", new Type[] {}); 
object magicValue = getAllMethod.Invoke(myClassInstance, null); 

這導致(上以上代碼的最後一行):

無法在ContainsGenericParameters類型或方法上執行後期操作真正。

好的,第二次嘗試:

MethodInfo getAllMethod = myClassType.GetMethod("GetAll", new Type[] {}); 
getAllMethod = getAllMethod.MakeGenericMethod(typeof(object)); 
object magicValue = getAllMethod.Invoke(myClassInstance, null); 

這導致(在上述第二代碼最後一行):

System.Collections.Generic.IList`1 [T] GETALL ()不是GenericMethodDefinition。 MakeGenericMethod只能在MethodBase.IsGenericMethodDefinition爲true的方法上調用。

我在這做錯了什麼?

+0

'baseRepo'在最後一行來自哪裏?它不應該是'myClassInstance'嗎? – 2012-01-27 15:51:20

+0

您的示例代碼必須在此行中有一個錯誤:MethodInfo getAllMethod = myClassInstance.GetMethod(「GetAll」,new Type [] {}); – usr 2012-01-27 15:52:07

+0

是的,OP可能使用了''myClassType''而不是''構造''。我糾正之後,它爲我工作。 – 2012-01-27 15:53:29

回答

6

我已經試過這和它的作品:

// Create generic type 
Type myClassType = typeof(MyClass<>); 
Type[] typeArgs = { typeof(object) }; 
Type constructed = myClassType.MakeGenericType(typeArgs); 

// Create instance of generic type 
var myClassInstance = Activator.CreateInstance(constructed);  

// Find GetAll() method and invoke 
MethodInfo getAllMethod = constructed.GetMethod("GetAll"); 
object result = getAllMethod.Invoke(myClassInstance, null); 
+0

Thx - 這是一個愚蠢的錯誤...'construct.GetMethod(「GetAll」);'當然是正確的,或者在我的情況下'myClassInstance.GetMethod(「GetAll」,new Type [] {});' – sl3dg3 2012-01-27 16:08:34

0

如果這是你如何使用它,爲什麼你打擾使MyClass通用?這將是顯著快:

public class MyClass 
{ 
    public IList GetAll() 
    { 
     return null; // of course, something more meaningfull happens here... 
    } 
} 

,然後就打電話

var myObject = new MyClass(); 
var myList = myObject.GetAll(); 
+0

我的猜測是將它作爲Type對象只是爲了這個例子,使其儘可能容易理解 – eouw0o83hf 2012-01-27 15:48:22

+0

準確地說:這是一個簡化的例子。爲什麼會這樣呢?爲什麼我必須在其他地方使用反思? – sl3dg3 2012-01-27 15:52:05

1

我已經注意到了(不知道這是否只是在您的示例中出現錯誤)您的代碼存在問題。 myClassInstance將是object,因此您不能撥打GetMethod(...)。我想你可能會打電話給那種類型。其次,你傳遞baseRepo作爲調用該方法的對象 - 當然,你想調用該類型的實例化方法 - 在這種情況下,變量myClassInstance

如果您修改代碼這種方式,你應該有類似下面的代碼(其中,測試時,工作):

Type classType = typeof(MyClass<>); 
Type[] typeArgs = { typeof(object) }; 
Type fullClassType = classType.MakeGenericType(typeArgs); 

var classInstance = Activator.CreateInstance(fullClassType); 

MethodInfo method = fullClassType.GetMethod("GetAll", new Type[0]); 
object result = method.Invoke(classInstance, null); 
1

這工作:

public static void TestMethod() 
{ 
    Type myClassType = typeof(MyClass<>); 
    Type[] typeArgs = { typeof(object) }; 
    Type constructed = myClassType.MakeGenericType(typeArgs); 
    var myClassInstance = Activator.CreateInstance(constructed); 

    MethodInfo getAllMethod = constructed.GetMethod("GetAll", new Type[] { }); 
    object magicValue = getAllMethod.Invoke(myClassInstance, null); 
} 

有一些錯誤在你的代碼中,如下所示:

  • 你需要在泛型類的類型對象上調用GetMethod(...)(不是實例)。
  • getAllMethod.Invoke(...)需要使用Activator創建的通用類的實例。