2013-02-10 1 views
5

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

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

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

+0

Я думаю, что это возможно. Эрик Липперт однажды сообщил о возможном описании оператора C#, который использовал бы это. – usr

+0

Не могли бы вы дать небольшой контекст по причине, чтобы сделать проблему немного яснее для меня/нас? –

+0

@usr [Статья, о которой вы говорите] (http://blogs.msdn.com/b/ericlippert/archive/2009/05/21/in-foof-we-trust-a-dialogue.aspx) является о синтаксических проблемах 'infoof', а не о том, как это можно реализовать. – svick

ответ

8

Вы не можете просто загрузить какой-либо общий объект в 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()); 
+0

Работал отлично! –

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

  • Нет связанных вопросов^_^