Come definire un DynamicMethod per un delegato con un parametro simile a out
, come questo?DynamicMethod e parametri esterni?
public delegate void TestDelegate(out Action a);
Diciamo che voglio semplicemente un metodo che imposta l'argomento a
a null
quando chiamo il metodo.
Nota che un modo probabilmente migliore per gestirlo sarebbe quello di rendere il metodo restituito al delegato Action
, ma questa è solo una parte semplificata di un progetto più grande, e il metodo in questione restituisce già un valore, I è necessario gestire il parametro out
in aggiunta ad esso, quindi la domanda.
ho provato questo:
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);
}
}
}
Tuttavia, ottengo questo:
VerificationException was unhandled:
Operation could destabilize the runtime.
sulla linea del(out a);
.
Si noti che se commento le due righe che caricano un null nello stack e tenta di memorizzarlo nell'argomento, il metodo viene eseguito senza eccezioni.
Edit: È questo l'approccio migliore?
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stind_Ref);
È davvero necessario creare un metodo dinamico? perché non implementare semplicemente il metodo in una classe che può essere configurata per fare ciò che vuoi in fase di runtime? –
Deve essere davvero un metodo dinamico, questo è uno sforzo di ottimizzazione last-stop per ottenere un enorme albero delle chiamate basato sulla riflessione da eseguire più velocemente. Finora il sovraccarico dell'utilizzo dell'approccio metodo dinamico contro il codice esistente sembra essere circa dell'85% in meno, e questo è il codice che verrà chiamato migliaia di volte al secondo. Le misurazioni mostrano che un bel po 'di CPU è legata al codice di riflessione esistente. –