Я пытаюсь вызвать внутренний метод из динамически сгенерированного. Код il прост: ldarg_0, callvirt, ret.
Выполнение метода завершается ошибкой TypeLoadException, в которой говорится, что он не может загрузить тип, для которого определен внутренний метод.
Когда я думаю об этом, это кажется логичным, потому что сборка узла динамического метода не является другом сборке объявления типа метода.
Однако я ожидал, что динамический метод по-прежнему будет работать, как и Delegate.CreateDelegate. В конце концов, мне удалось получить MethodInfo внутреннего метода, поэтому барьер разрешений остался позади.
В любом случае, вопрос в том, «можно ли вызвать внутренний метод из динамически сгенерированного?»
Спасибо.
РЕДАКТИРОВАТЬ:
Вот простой пример кода, демонстрирующий проблему:
using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
namespace A
{
internal class Data
{
internal string String { get; set; }
}
public static class Program
{
public static void Main()
{
Expression<Func<Data, string>> expr = x => x.String;
var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true);
var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo);
var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) });
var gen = dm.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Castclass, typeof(Data));
gen.Emit(OpCodes.Callvirt, getterInfo);
gen.Emit(OpCodes.Ret);
var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>));
var data = new Data() { String = "Hello" };
var str1 = getter1(data);
var str2 = getter2(data);
}
}
}
В коде я создаю два делегата открытого экземпляра для доступа к свойству экземпляра Data.String:
- введите безопасный getter1, используя Delegate.CreateDelegate
- введите unsafe getter2, используя DynamicMethod
Типобезопасный делегат, созданный Delegate.CreateDelegate, работает, в то время как тот, который использует DynamicMethod, не работает с TypeLoadException.
Обратите внимание, что я не хочу использовать подход, безопасный для типов, поскольку контекст, в котором создается геттер, не является универсальным. Конечно, я могу решить эту проблему, но теперь вопрос стоит принципиальный - почему DynamicMethod не работает там, где успешно Delegate.CreateDelegate?