mardi 25 juillet 2017

How can I emit a dynamic method returning a ref?

I'm navigating the ins and outs of ref returns, and am having trouble emitting a dynamic method which returns by ref.

Handcrafted lambdas and existing methods work as 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 a dynamic method fails. Note: I'm using Sigil here. Apologies, I'm less familiar with 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 at NewDynamicMethod, throwing 'The return Type contains some invalid type (i.e. null, ByRef)'. Which makes sense, since I understand that under the hood WidgetMeasurer returns an Int32&.

The question is, is there some first- or third-party technique I can employ to emit code mimicking the first two examples (which I empirically know work correctly)? If not, is this restriction a logical one?





Aucun commentaire:

Enregistrer un commentaire