我使用Reflection从通用方法中检索methodInfo:
public void Sponsor<T>(int id) where T : BaseIdea, new() {
// Do something
}
这很好。但是,如果该方法具有以下约束:
q.Sponsor<object>
q.Sponsor<BaseIdea>
(在调用方内部)无法编译:
类型“对象”不能用作泛型中的类型参数“ T” 类型或方法'ModuleBaseLogic.Sponsor(int)'没有隐式 从“对象”到“ BaseIdea”的引用转换。
我尝试用.env
替换它,但这也不起作用
答案 0 :(得分:2)
这里有一些例子,如果您有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.
}
答案 1 :(得分:2)
目前应该可以使用:
public abstract class BaseIdea {}
public class ConcreteIdea : BaseIdea {}
public class ModuleBaseLogic {
public void Sponsor<T>(int id)
where T : BaseIdea, new()
{
// Do something
}
}
public class Caller {
protected static MethodInfo GetMethod<T>(Expression<Action<T>> expr)
{
return ((MethodCallExpression)expr.Body).Method.GetGenericMethodDefinition();
}
public Caller() {
int id = 1;
MethodInfo method = GetMethod<ModuleBaseLogic>(q => q.Sponsor<ConcreteIdea>(id));
}
}
给出一些解释: 像乔恩·斯基特(Jon Skeet)一样,对于具有任何通用约束的任何方法,object都不可以是通用参数。 BaseIdea不能是通用参数,因为它是抽象参数,这对于基类通常是必需的。 最简单的参数是一个具体类,它是从BaseIdea派生的,它由我的ConcreteIdea-class给出。 正如kara所提到的,new()约束还需要一个无参数的构造函数,该构造函数也可以是隐式构造函数(默认构造函数)。
答案 2 :(得分:2)
另一种方法是使用一个表达式,该表达式通过使用nameof()
运算符确定该方法的名称,然后实际执行该表达式。
public class Caller
{
protected static MethodInfo GetMethod<T>(Expression<Func<T, string>> expr) where T: class
{
// Execute the expression. We will get the method name.
string methodName = expr.Compile()(null);
// Return generic method information by name of the method
return typeof(T).GetMethod(methodName);
}
public Caller()
{
MethodInfo method = GetMethod<ModuleBaseLogic>(m => nameof(m.Sponsor));
}
}
注意:当使用相同名称的方法有多个重载时,这将不起作用。