c# - How to call Action<string, bool> from il generator -
in example code trying invoke anonymous action il generator. not sure if , how can load reference delegate , how call it. can if onfunctioncall
static method not property.
public delegate void testdelegate(); public static class exampleone { public static action<string, bool> onfunctioncall => (message, flag) => console.writeline("example"); } public static class exampletwo { public static ttype createdelegate<ttype>(action<string, bool> onfunctioncall) ttype : class { var method = new dynamicmethod($"{guid.newguid()}", typeof(void), type.emptytypes, typeof(ttype), true); ilgenerator il = method.getilgenerator(); // emit code invoke unmanaged function ... // loading first string argument il.emit(opcodes.ldstr, method.name); // not sure here how load boolean value stack il.emit(opcodes.ldc_i4_0); // line doesn't work // example 2 has no idea exampleone // possible load reference of action<string, bool> stack , call ? il.emit(opcodes.call, onfunctioncall.method); il.emit(opcodes.ret); return method.createdelegate(typeof(testdelegate)) ttype; } } public class program { public static void main(string[] args) => exampletwo .createdelegate<testdelegate>(exampleone.onfunctioncall) .invoke(); }
you have pass information delegate want invoke stored. convenience way accept memberexpression
, otherwise accepting memberinfo
would work too. have @ modified code:
public delegate void testdelegate(); public static class exampleone { public static action<string, bool> onfunctioncall => (message, flag) => console.writeline("onfunctioncall"); public static action<string, bool> onfunctioncallfield = (message, flag) => console.writeline("onfunctioncallfield"); } public static class exampletwo { public static ttype createdelegate<ttype>(expression<func<object>> expression) ttype : class { var body = expression.body memberexpression; if (body == null) { throw new argumentexception(nameof(expression)); } var method = new dynamicmethod($"{guid.newguid()}", typeof(void), type.emptytypes, typeof(ttype), true); ilgenerator il = method.getilgenerator(); // typed invoke method , // call getter or load field methodinfo invoke; if (body.member propertyinfo pi) { invoke = pi.propertytype.getmethod("invoke"); il.emit(opcodes.call, pi.getgetmethod()); } else if (body.member fieldinfo fi) { invoke = fi.fieldtype.getmethod("invoke"); il.emit(opcodes.ldsfld, fi); } else { throw new argumentexception(nameof(expression)); } il.emit(opcodes.ldstr, method.name); il.emit(opcodes.ldc_i4_0); il.emit(opcodes.callvirt, invoke); il.emit(opcodes.ret); return method.createdelegate(typeof(testdelegate)) ttype; } } public class program { public static void main(string[] args) { exampletwo .createdelegate<testdelegate>(() => exampleone.onfunctioncall) .invoke(); exampletwo .createdelegate<testdelegate>(() => exampleone.onfunctioncallfield) .invoke(); console.readline(); } }
the code running on .net core 2.0.
Comments
Post a Comment