2013-03-20 1 views
1

Я создаю сборку с использованием Reflection.Emit и хочу, чтобы она вызывала специальный обратный вызов.Вызов лямбды из сборщика, генерирующего отражение

Вот упрощенная версия кода:

public void Call(ILGenerator il, Delegate action) 
{ 
    il.Emit(OpCodes.Call, action.Method); 
} 

public static void DoStuff() 
{ 
    Console.WriteLine("Action invoked!"); 
} 

Call(CurrentMethod.ILGenerator, DoStuff); 

Этот код работает так же, как и ожидалось.

Однако, я хочу передать лямбда-выражения, например:

Call(CurrentMethod.ILGenerator,() => Console.WriteLine("test")); 

На этот раз следующее исключение:

System.MethodAccessException: Покушение методом».run() 'для доступа к методу' Compiler.Test.ImportedFunctions.b__0() 'не удалось.

Есть ли способ обойти его?

+0

Действительно ли код работает под полным доверием? – Greg

+0

@Greg, сборка создается с помощью 'AppDomain.CurrentDomain.DefineDynamicAssembly (name, AssemblyBuilderAccess.RunAndSave)'. Как проверить настройки доверия? – Impworks

+0

@Impworks: Если вы можете это сделать, вы уже работаете под полным доверием :) – leppie

ответ

1

Delegate это тоже общий. Попробуйте Action.

НО БУДЬ ПРЕДУПРЕЖДЕН!

Если целевое свойство делегата не равно null, это невозможно.

Вы можете обойти это, временно сохраняя значение цели в статическом поле.

Возможное решение (модификаторы испускаемые):

class Foo { static object target; } 

public void Call(ILGenerator il, Action action) 
{ 
    Foo.target = action.Target; 
    il.Emit(OpCodes.Ldsfld, typeof(Foo).GetField("target"); 
    il.Emit(OpCodes.Callvirt, action.Method); 
} 

Если вы работаете в однотридовой среде без каких-либо рекурсивных вызовов, это будет работать.

Для рекурсивной среды вам необходимо использовать динамическое связывание для Foo.target, которое не доступно на C#.

К счастью I have written such a facility для C# уже.

+0

К несчастью, 'Func <>' и 'Action <>' объекты, созданные из lambdas, не являются статическими. Я попробую попробовать. – Impworks

+1

Это только нестатический, если делегат захватывает переменные. – leppie

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

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