I look through all the inputs and outputs of ref, and I am unable to fix the dynamic method that ref returns.
Handmade lambds 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 use Sigil here. Sorry, 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 is not true when NewDynamicMethodthrowing 'The return Type contains some invalid type (i.e. null, ByRef)'. This makes sense, as I understand that it is WidgetMeasurercoming back under the hood Int32&.
The question is, is there any first or third party method that I can use to emit code that mimics the first two examples (which I empirically know is working correctly)? If not, is this a logical restriction?
EDIT: System.Reflection.Emit ( ):
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));
}