在下面的代码中,我应该如何设置变量"paramType",使其与GetMethod()调用中显示的方法相匹配?
下面的代码与示例类中的方法不匹配(methodInfo为null)。
using System;
using System.Linq.Expressions;
public class MyClass<TClass>
{
public void MyMethod<TMethod>( Expression<Func<TClass, TMethod>> expr )
{
}
}
class Program
{
static void Main( string[] args )
{
var classType = typeof( MyClass<> );
// What should this really be?
var paramType = typeof( Expression<> ).MakeGenericType( typeof( Func<,> ) );
var methodInfo = classType.GetMethod( "MyMethod", new Type[] { paramType } );
}
}
编辑:我知道如何使用GetMethods
或其他形式的迭代/假设来获得MethodInfo
。我的问题是关于如何设置paramType
的System.Type
,如果它甚至可能为它生成一个System.Type
。
编辑2:为了更具体地解决问题,我更新了代码:
using System;
using System.Linq.Expressions;
public class MyClass<TClass>
{
public void MyMethod<TMethod>( Expression<Func<TClass, TMethod>> expr )
{
Console.WriteLine( "Type: {0} Return: {1}", typeof( TClass ).Name, typeof( TMethod ).Name );
}
public void MyMethod<TMethod>( TMethod param )
{
}
}
class Program
{
public int MyProperty { get; set; }
static void Main( string[] args )
{
var classType = typeof( MyClass<> );
var typeClass = typeof( Program );
var typeMethod = typeof( int );
// What should this really be?
var paramType = typeof( Expression<> )
.MakeGenericType( typeof( Func<,> )
.MakeGenericType( typeClass, typeMethod )
);
var methodInfo = classType
.MakeGenericType( typeClass )
.GetMethod( "MyMethod", new Type[] { paramType } );
}
}
这也不工作-这个不同版本的paramType
与更多的信息似乎不匹配。
在非一般情况下,有人可能希望像这样调用"MyMethod":
// I want to use a MethodInfo to perform this function:
new MyClass<Program>().MyMethod( _program => _program.MyProperty );
我相信你的问题的答案是,"没有办法做到这一点"。
由于GetMethod在进行查找时不能"MakeGenericMethod",因此您有一个具有已知(TClass)和未知(TMethod)的泛型参数的方法。当方法的一些参数已知时,反射不能查找方法。
注意-即使你知道TMethod应该是什么(在你的例子中是"int"),这将需要我在前一段引用的"MakeGenericMethod"。
要做到这一点,您需要知道泛型类型,否则我认为您的任务是不可能的。
如果你的意图是在泛型类知道它的任何类型之前为它创建一个泛型方法,这样你就可以在以后调用MakeGenericType
时使用你的两个类型,这是不可能的。
这可以通过调用typeof(MyClass<>).GetMethod("MyMethod")
来显示,它将返回null。
另一方面,如果你知道具体的类型,那就很容易了:
static MethodInfo GetMethod(Type classType, Type methodType)
{
var genericClassType = typeof(MyClass<>).MakeGenericType(classType);
var methodInfo = genericClassType.GetMethod("MyMethod");
var genericMethodInfo = methodInfo.MakeGenericMethod(methodType);
return genericMethodInfo;
}
注意,我没有为Expression<Func<TClass,TMethod>>
参数创建泛型类型。
当您创建genericClassType
并在其上调用GetMethod
时,CLR还不知道TMethod
是什么类型。这只有在调用methodInfo
上的MakeGenericType
时才知道。因此,如果您使用完全参数化的Expression<Func<TClass,TMethod>>
类型调用GetMethod
,它将无法找到该方法。
这就是为什么您需要在没有参数类型的情况下调用genericClassType.GetMethod("MyMethod")
,并且可能必须过滤它,如果方法是重载的。之后,您可以调用MakeGenericMethod(methodType)
并获得完全参数化的methodInfo对象。