2012-01-27 83 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创建的通用类的实例。