Как создать метод с предварительно загруженной локальной переменной MethodInfo?

Я хотел бы создать метод с переменной, что я могу сделать. Но я хотел бы сохранить в этой переменной объект MethodInfo, который является ссылкой на другой (не испускаемый) метод.

Я мог бы испустить коды операций для вызова typeof (someClass) .GetMethod (...), но было бы более эффективно, если бы я мог просто загрузить токен для этого MethodInfo и запечь его непосредственно в переменной.

Итак, перефразируя, я пытаюсь выяснить, можно ли испустить, скажем, код операции «загрузить объект» и передать ему объект во время выпуска, который будет загружен в стек во время выполнения. (OpCodes.Ldobj выдал какую-то ошибку, когда я попробовал это). Или я вынужден выдавать коды операций, которые будут делать это во время выполнения?


person Jay Sullivan    schedule 10.02.2013    source источник
comment
Думаю, это возможно. Эрик Липперт однажды написал в блоге о возможной информации об операторе C #, который мог бы это использовать.   -  person usr    schedule 10.02.2013
comment
Не могли бы вы дать небольшой контекст о причине, чтобы прояснить проблему для меня / нас?   -  person Kieren Johnstone    schedule 10.02.2013
comment
@usr Статья, о которой вы говорите, посвящена синтаксическим проблемам infoof, а не тому, как это можно реализовать.   -  person svick    schedule 10.02.2013


Ответы (1)


Вы не можете просто загрузить какой-либо общий объект в IL, потому что нет способа сохранить его в IL (за исключением некоторых специальных типов, таких как string). Вы можете обойти это, используя сериализацию (для типов, которые ее поддерживают), но я не думаю, что вы этого хотите. Кроме того, ldobj служит совсем другой цели.

Но вы можете сделать это для MethodInfo способом, очень похожим на то, что C # делает для оператора typeof. Это означает:

  1. используя инструкцию ldtoken, чтобы получить RuntimeMethodHandle
  2. позвонив MethodBase.GetMethodFromHandle(), чтобы получить MethodBase
  3. преобразовать его в MethodInfo

Весь код для создания метода, возвращающего MethodInfo, может выглядеть так:

MethodInfo loadedMethod = …;
var getMethodMethod = typeof(MethodBase).GetMethod(
    "GetMethodFromHandle", new[] { typeof(RuntimeMethodHandle) });

var createdMethod = new DynamicMethod(
    "GetMethodInfo", typeof(MethodInfo), Type.EmptyTypes);

var il = createdMethod.GetILGenerator();
il.Emit(OpCodes.Ldtoken, loadedMethod);
il.Emit(OpCodes.Call, getMethodMethod);
il.Emit(OpCodes.Castclass, typeof(MethodInfo));
il.Emit(OpCodes.Ret);

var func = (Func<MethodInfo>)createdMethod.CreateDelegate(typeof(Func<MethodInfo>));
Console.WriteLine(func());
person svick    schedule 10.02.2013