c# - How can I emit a dynamic method returning a ref? -


i'm navigating ins , outs of ref returns, , having trouble emitting dynamic method returns ref.

handcrafted lambdas , existing methods work expected:

class widget {     public int length; } delegate ref int widgetmeasurer(widget w);  widgetmeasurer getmeasurera() {     return w => ref w.length; }  static ref int measurewidget(widget w) => ref w.length; widgetmeasurer getmeasurerb() {     return measurewidget; } 

but emitting dynamic method fails. note: i'm using sigil here. apologies, i'm less familiar system.reflection.emit.

widgetmeasurer getmeasurerc() {     fieldinfo lengthfield = typeof(widget).getfield(nameof(widget.length));     var emitter = emit<widgetmeasurer>.newdynamicmethod()         .loadargument(0)         .loadfieldaddress(lengthfield)         .return();     return emitter.createdelegate(); } 

this fails @ newdynamicmethod, throwing 'the return type contains invalid type (i.e. null, byref)'. makes sense, since understand under hood widgetmeasurer returns int32&.

the question is, there first- or third-party technique can employ emit code mimicking first 2 examples (which empirically know work correctly)? if not, restriction logical one?

edit: i've tried equivalent system.reflection.emit code , got same exception (as expected):

widgetmeasurer getmeasurerd() {     fieldinfo lengthfield = typeof(widget).getfield(nameof(widget.length));      type returntype = typeof(int).makebyreftype();     type[] paramtypes = { typeof(widget) };     dynamicmethod method = new dynamicmethod("", returntype, paramtypes);      ilgenerator il = method.getilgenerator();     il.emit(opcodes.ldarg_0);     il.emit(opcodes.ldflda, lengthfield);     il.emit(opcodes.ret);      return (widgetmeasurer)method.createdelegate(typeof(widgetmeasurer)); } 

i don't know why limitation exists dynamicmethod, following worked me. 1 difference defining our own dynamic assembly hand. difference since separate assembly, widget needs public (or if name dynamic assembly appropriately use internalsvisibleto on parent assembly).

static void main(string[] args) {     var widget = new widget();     getlengthmeasurer()(widget) = 7;     console.writeline(widget.length); }  private static widgetmeasurer getlengthmeasurer() {     var fieldinfo = typeof(widget).getfield("length");     var asmname = new assemblyname("widgetdynamicassembly." + guid.newguid().tostring());     var asmbuilder = appdomain.currentdomain.definedynamicassembly(asmname, assemblybuilderaccess.runandcollect);     var modulebuilder = asmbuilder.definedynamicmodule("<module>");     var typebuilder = modulebuilder.definetype("widgethelper");     var methodbuilder = typebuilder.definemethod("getlength", methodattributes.static | methodattributes.public, typeof(int).makebyreftype(), new[] { typeof(widget) });     var ilgen = methodbuilder.getilgenerator();     ilgen.emit(opcodes.ldarg_0);     ilgen.emit(opcodes.ldflda, fieldinfo);     ilgen.emit(opcodes.ret);     var type = typebuilder.createtype();     var mi = type.getmethod(methodbuilder.name);     var del = (widgetmeasurer)mi.createdelegate(typeof(widgetmeasurer));     return del; } 

output:

7


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -