2015-05-29 3 views
1

В приведенном ниже коде, как я должен устанавливать переменную «paramType» так, чтобы она соответствовала методу, показанному в вызове GetMethod()?Правильный тип параметра для 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 }); 
    } 
} 

EDIT: Я знаю, как получить MethodInfo с помощью GetMethods или какой-либо другой формы итерации/предположения. Мой вопрос конкретно в том, как установить System.TypeparamType, если его даже возможно сгенерировать для него System.Type.

EDIT 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); 
+0

http://stackoverflow.com/questions/4035719/getmethod-for-generic-method – Dreamweaver

+0

http://stackoverflow.com/questions/269578/get-a-generic-method-without-using-getmethods – Dreamweaver

+0

Спасибо для ссылок, но ни один из них не отвечает на мой конкретный вопрос. Кажется, что один ответ включает итерацию через члены Типа, в то время как другой не вставляет общий тип в другой общий тип. – Veldaeven

ответ

1

Я верю, что ответ на ваш вопрос: «Невозможно это сделать».

Поскольку GetMethod не может «MakeGenericMethod» при его поиске, у вас есть метод с одним общим параметром, который известен (TClass), и тот, который не является (TMethod). Отражение не может искать метод, когда известны некоторые, но не все, параметры.

Примечание. Даже если вы знаете, что должен быть TMethod («int» в вашем примере), для этого потребуется «MakeGenericMethod», на который я ссылался в предыдущем абзаце.

+0

Я думаю, что так и есть - я не могу найти лучшего ответа. – Veldaeven

0

Для этого вам необходимо знать общие типы, я не думаю, что ваша задача будет возможно в противном случае.

Если вы намереваетесь создать общий методinfo для общего класса, прежде чем он узнает какой-либо его тип, вы можете позже называть 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. Поэтому, если вы назовете с полностью параметризованным типом Expression<Func<TClass,TMethod>>, он не найдет этот метод.

Именно поэтому вам необходимо позвонить genericClassType.GetMethod("MyMethod") без параметров и, возможно, придется его фильтровать, если метод перегружен. Впоследствии вы можете позвонить MakeGenericMethod(methodType) и иметь свой полностью параметризованный объект methodInfo.

+0

Извините, это не совсем то, что мне нужно. Я снова отредактирую вопрос с большим фоном. – Veldaeven

+0

Более конкретно - параметры GetMethod без параметров будут неоднозначными, поэтому мне нужен параметр Type в первую очередь. – Veldaeven

+0

Вы не сможете вызвать GetMethod для общего метода, параметры которого зависят от типа общего метода (именно этого вы и пытаетесь сделать). CLR не знает, какой тип будет иметь общий метод, прежде чем называть MakeGenericMethod. Поэтому вам нужно вызвать GetMethod без параметров и в случае необходимости выполнить итерацию всех найденных методов. Нет лучшего способа грустно, вы не можете создать общий тип с отражением, поскольку параметры типа еще не установлены. –

Смежные вопросы