首页 > 解决方案 > 使用反射调用具有约束的泛型方法

问题描述

我使用反射从泛型方法中检索 methodInfo:

public abstract class BaseIdea {}    

public class ModuleBaseLogic {
  public void Sponsor<T>(int id) {
    // Do something
  }
}

public class Caller {
  protected static MethodInfo GetMethod<T>(Expression<Action<T>> expr)
  {
    return ((MethodCallExpression)expr.Body).Method.GetGenericMethodDefinition();
  }

  public Caller() { 
    MethodInfo method = GetMethod<ModuleBaseLogic>(q => q.Sponsor<object>(id));
  }
}

这工作正常。但是,如果该方法具有以下约束:

public void Sponsor<T>(int id)  where T : BaseIdea, new() {
  // Do something
}

q.Sponsor<object>内部调用者)不编译:

类型“object”不能用作泛型类型或方法“ModuleBaseLogic.Sponsor(int)”中的类型参数“T”。没有从“object”到“BaseIdea”的隐式引用转换。

我尝试将其替换为,q.Sponsor<BaseIdea>但这也不起作用

标签: c#genericsreflectionconstraints

解决方案


这里有一些例子,如果你有什么是允许的,什么是不允许的where T : SomeClass, new()

public abstract class MyBaseClass { }
public class MyClass : MyBaseClass { }
public class MyClass2 : MyBaseClass
{
    public MyClass2(int x)
    {

    }
}

public class SomeOtherClass { }

public static void MyMethod<T>() where T : MyBaseClass, new() { }

public static void Main(string[] args)
{
    MyMethod<MyBaseClass>(); // Does not work because MyBaseClass is abstract
    MyMethod<MyClass>(); // works because T is MyClass, which is derived from MyBaseClass
    MyMethod<MyClass2>(); // Doesn't work because it doesn't have a Std.Constructor "MyClass2()" it has a constructor with parameters "MyClass2(int x)"
    MyMethod<SomeOtherClass>(); // Doesn't work because T is SomeOtherClass, and it's not derived from MyBaseClass.
}

推荐阅读