È possibile visualizzare il codice IL generato quando si chiama Compile () su un albero espressione? Considera questo esempio molto semplice:
class Program
{
public int Value { get; set; }
static void Main(string[] args)
{
var param = Expression.Parameter(typeof(Program));
var con = Expression.Constant(5);
var prop = Expression.Property(param, typeof(Program).GetProperty("Value"));
var assign = Expression.Assign(prop, con);
Action<Program> lambda = Expression.Lambda<Action<Program>>(assign, param).Compile();
Program p = new Program();
lambda(p);
//p.Value = 5;
}
}
Ora, l'albero delle espressioni fa quello che dice l'ultima riga di Main
. Compila l'applicazione, quindi aprila in Reflector. Puoi vedere il codice IL di p.Value = 5;
questo è il compito. Ma l'albero delle espressioni è stato creato e compilato in fase di runtime. È possibile visualizzare il codice IL risultante dalla compilazione?
Sì! Usa questo strumento:
https://github.com/drewnoakes/il-visualizer
Questo è stato incredibilmente utile durante l'implementazione e il debug di Compile, come sono sicuro che puoi immaginare.
Crea un DynamicAssembly, quindi un DynamicModule, DynamicType e DynamicMethod. Rendi pubblico e statico quel metodo e passalo al metodo CompileTo () sul lambda. Quando si effettua il flag di assemblaggio come Salva. Quindi chiama il metodo Save () e passa un percorso. Sarà scritto sul disco. Aprilo nel riflettore.
Qualcosa di simile a:
var da = AppDomain.CurrentDomain.DefineDynamicAssembly(
new AssemblyName("dyn"), // call it whatever you want
AssemblyBuilderAccess.Save);
var dm = da.DefineDynamicModule("dyn_mod", "dyn.dll");
var dt = dm.DefineType("dyn_type");
var method = dt.DefineMethod(
"Foo",
MethodAttributes.Public | MethodAttributes.Static);
lambda.CompileToMethod(method);
dt.CreateType();
da.Save("dyn.dll");