GetMethod的正确参数类型

时间:2015-05-29 21:48:49

标签: c# reflection

在下面的代码中,我应该如何设置变量" 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 } );
    }
}

编辑:我知道如何使用MethodInfo或其他形式的迭代/假设来获取GetMethods。我的问题具体是关于如何设置System.Type paramType,如果它甚至可以为它生成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的不同版本与更多信息似乎并不匹配。

在非一般情况下,有人可能想要打电话给#34; MyMethod&#34;像这样:

// I want to use a MethodInfo to perform this function:
new MyClass<Program>().MyMethod( _program => _program.MyProperty );

2 个答案:

答案 0 :(得分:1)

我相信你的问题的答案是,“没有办法做到这一点”。

由于GetMethod在执行查找时无法“MakeGenericMethod”,因此您有一个方法,其中包含一个已知的通用参数(TClass)和一个不是(TMethod)的通用参数。当一些(但不是全部)参数已知时,反射无法查找方法。

注意 - 即使你知道TMethod应该是什么(在你的例子中是“int”),这将需要我在前一段中引用的“MakeGenericMethod”。

答案 1 :(得分:0)

要做到这一点,你需要知道通用类型,我不认为你的任务是可能的。

如果您打算为泛型类创建一个泛型的methodinfo,那么在它知道任何类型之前,您可以稍后用它上面的两种类型调用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将是什么类型。只有在MakeGenericType上致电methodInfo时,才会知道此事。因此,如果您使用完全参数化的GetMethod类型调用Expression<Func<TClass,TMethod>>,则无法找到该方法。

这就是为什么你需要在没有参数类型的情况下调用genericClassType.GetMethod("MyMethod"),并且如果方法过载则可能必须对其进行过滤。然后,您可以调用MakeGenericMethod(methodType)并使用完全参数化的methodInfo对象。