2009-08-18 17 views
5

Jak zdefiniować metodę DynamicMethod dla delegata o parametrze out?DynamicMethod i out-parametry?

public delegate void TestDelegate(out Action a); 

Powiedzmy, że po prostu chcą metodę, która ustawia a argument null kiedy wywołać metodę.

Zauważ, że wiem, że prawdopodobnie lepszym sposobem na obsłużenie tego byłoby uczynienie metody zwracania delegata Action, ale jest to tylko uproszczona część większego projektu, a dana metoda już zwraca wartość, I oprócz tego trzeba obsługiwać parametr out, stąd pytanie.

Próbowałem to:

using System; 
using System.Text; 
using System.Reflection.Emit; 

namespace ConsoleApplication8 
{ 
    public class Program 
    { 
     public delegate void TestDelegate(out Action a); 

     static void Main(String[] args) 
     { 
      var method = new DynamicMethod("TestMethod", typeof(void), 
       new Type[] { typeof(Action).MakeByRefType() }); 
      var il = method.GetILGenerator(); 

      // a = null; 
      il.Emit(OpCodes.Ldnull); 
      il.Emit(OpCodes.Starg, 0); 

      // return 
      il.Emit(OpCodes.Ret); 

      var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate)); 
      Action a; 
      del(out a); 
     } 
    } 
} 

jednak uzyskać to:

VerificationException was unhandled: 
Operation could destabilize the runtime. 

na linii del(out a);.

Uwaga: jeśli skomentuję dwie linie, które ładują wartość null na stosie i próbuję zapisać ją w argumencie, metoda działa bez wyjątków.


Edit: Czy to jest najlepszym podejściem?

il.Emit(OpCodes.Ldarg_0); 
il.Emit(OpCodes.Ldnull); 
il.Emit(OpCodes.Stind_Ref); 
+0

Czy naprawdę potrzebne jest stworzenie metody dynamicznej? dlaczego nie wystarczy zaimplementować metodę w klasie, która może być skonfigurowana do robienia tego, co chcesz w czasie wykonywania? –

+0

To naprawdę musi być metoda dynamiczna, jest to wysiłek optymalizacji ostatniej chwili, aby uzyskać potężne drzewko wywołania oparte na odbiciu, aby wykonać je szybciej. Jak dotąd obciążenie związane z metodą dynamicznego podejścia wbrew istniejącemu kodowi wydaje się być o około 85% mniejsze, a to jest kod, który będzie się nazywał tysiące razy na sekundę. Pomiary pokazują, że dość sporo procesora jest zawiązanych w istniejącym kodzie odbicia. –

Odpowiedz

6

out argument jest po prostu ref Argument z OutAttribute przyłożonego do parametru.

Aby zapisać do argumentu o wartości -us, należy użyć kodu operacji stind, ponieważ sam argument jest zarządzanym wskaźnikiem do rzeczywistej lokalizacji obiektu.

ldarg.0 
ldnull 
stind.ref 
Powiązane problemy