Reflection.Emit: Как надежно преобразовать MethodBuilder в RuntimeMethodInfo? - PullRequest
3 голосов
/ 13 июня 2010

После динамического создания типа и вызова TypeBuilder.CreateType я хочу создать делегат, который указывает на метод в новом типе.Но если я использую код вроде

loadedType = typeBuilder.CreateType();
myDelegate = (MyDelegate)Delegate.CreateDelegate(
                                  typeof(MyDelegate), methodBuilder);

Повторное использование methodBuilder в качестве methodInfo, я получаю исключение «MethodInfo должен быть RuntimeMethodInfo».Теперь обычно я могу повторно получить MethodInfo с

MethodInfo mi = loadedType.GetMethod(methodBuilder.Name);
myDelegate = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), mi);

Но мой класс может содержать несколько перегруженных методов с тем же именем.Как мне убедиться, что я правильно выбрал?Есть ли у методов какой-либо постоянный идентификатор, который я мог бы найти в загруженном типе?

Обновление: хорошо, вот что я использую для повторного получения MethodInfo.Я просто хотел бы быть уверен, что это работает во всех случаях.

private static MethodInfo ReacquireMethod(Type type, MethodInfo method)
{
    BindingFlags flags = BindingFlags.DeclaredOnly;
    flags |= (method.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic);
    flags |= (method.IsStatic ? BindingFlags.Static : BindingFlags.Instance);
    MethodInfo m = type.GetMethod(method.Name, flags, null,
                                          ParameterTypes(method), null);
    Debug.Assert(m != null);
    return m;
}

Ответы [ 2 ]

3 голосов
/ 13 июня 2010

Насколько я знаю, нет постоянного общего идентификатора.

Перегрузки метода различаются списками параметров, поэтому я предполагаю, что вам нужно будет вызвать GetParameters on methodBuilder и затем преобразовать возвращенный массив ParameterInfo[] в массив Type[] для передачи в соответствующую GetMethod перегрузку :

MethodInfo mi = loadedType.GetMethod(
    methodBuilder.Name,
    methodBuilder.GetParameters().Select(p => p.ParameterType).ToArray());
0 голосов
/ 13 июня 2010

Вам необходимо использовать перегрузку GetMethod, которая принимает массив типов. Перегрузки метода выбираются для привязки по передаваемым им параметрам. Поскольку вы на самом деле не вызываете метод при получении их метаданных с помощью отражения, вы должны предоставить упорядоченный массив объектов Type, чтобы получить правильный объект MethodInfo:

Метод Type.GetMethod (строка, тип [])

Используется как:

MethodInfo mi = loadedType.GetMethod(
    methodBuilder.Name, 
    new[] 
    { 
        typeof(string), 
        typeof(int) 
    }
);

Предполагается, что methodBuilder.Name - это «MyMethod», который связывает следующее:

public <returnType> MyMethod(string param1, int param2);

Помните, что возвращаемый тип не является частью сигнатуры метода, только имя метода и его типы параметров.

...