反射:使用通用列表调用方法作为结果

发布于 2024-12-29 11:59:30 字数 1195 浏览 2 评论 0原文

我有以下示例类:

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 为 true 的类型或方法执行后期绑定操作。

好的,第二次尝试:

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 的方法上调用。

我在这里做错了什么?

I have the following example-class:

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

And I would like to invoke GetAll with reflection:

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);

This results in (on last line of above code):

Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true.

Okay, second try:

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

This results in (on second last line of above code):

System.Collections.Generic.IList`1[T] GetAll() is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true.

What am I doing wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

甜宝宝 2025-01-05 11:59:30

我已经尝试过这个并且它有效:

// 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); 

I've tried this and it works:

// 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); 
单挑你×的.吻 2025-01-05 11:59:30

我注意到(不确定这是否只是您的示例中的错误)您的代码存在问题。 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);

I've noticed (not sure if it's just an error in your sample) that there is a problem with your code. myClassInstance will be of type object and so you cannot call GetMethod(...) on it. I think you may mean to call that on the type instead. Secondly, you are passing baseRepo as the object to invoke the method on - surely you want to invoke the method on the instantiation of the type - in this case, the variable myClassInstance?

If you modify your code this way, you should have something like the below code (which, when testing, works):

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);
谜泪 2025-01-05 11:59:30

这有效:

 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 创建的泛型类的实例。

This works:

 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);
 }

There are some errors in your code, as following:

  • You need to call GetMethod(...) on the type object of your generic class (not on instance).
  • getAllMethod.Invoke(...) requires the instance of the generic class you have created using Activator.
无妨# 2025-01-05 11:59:30

如果这就是您使用它的方式,那么您为什么要费心使 MyClass 通用呢?这会明显更快:

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

然后只需调用

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

If this is how you are using it, why are you bothering to make MyClass generic? This would be significantly faster:

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

and then just call

var myObject = new MyClass();
var myList = myObject.GetAll();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文