Можно ли вызвать внутренний метод из динамического метода in.NET?


Я пытаюсь вызвать внутренний метод из динамически генерируемого. Код il прост: ldarg_0, callvirt, ret.

Выполнение метода завершается ошибкой с TypeLoadException, говорящим, что он не может загрузить тип, на котором определен внутренний метод.

Когда я думаю об этом, это кажется логичным, потому что сборка узла динамического метода не является другом сборки типа объявления метода.

Однако я ожидал, что динамический метод все еще будет работать, так же, как Делегат.Вызове работает. В конце концов, мне удалось получить 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);
    }
  }
}

В коде я создаю два открытых делегата экземпляра для доступа к данным.Экземпляр строки свойство:

  • тип безопасный getter1 с помощью делегата.CreateDelegate
  • введите небезопасный геттер2, используя DynamicMethod

Типобезопасный делегат, созданный делегатом.CreateDelegate работает, в то время как тот, который использует DynamicMethod, терпит неудачу с TypeLoadException.

Обратите внимание, что я не хочу использовать типобезопасный подход, поскольку контекст, в котором создается геттер, не является универсальным. Конечно, я могу решить этот вопрос, но сейчас вопрос принципиальный-почему DynamicMethod терпит неудачу там, где делегат.Вызове преуспевает?
1 9

1 ответ:

Это сработает, если вы пропустите проверку видимости.

Измените эту строку

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true);

Смотрите msdn: (в частности таблицу со всеми правилами.)

Это из документа о конструкторе.

Тип Ограниченной Видимости: Система.Логическое значение true для пропуска JIT проверка видимости типов и членов доступ к MSIL динамической системы метод, с этим ограничением: уровень доверия сборок, которые содержать эти типы и члены должны будьте равны или меньше доверия уровень стека вызовов, который испускает динамический метод; в противном случае-ложь.