我正在浏览 ref 返回的来龙去脉,并且在发出由 ref 返回的动态方法时遇到问题。
手工制作的 lambda 表达式和现有方法按预期工作:
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;
}
但发出动态方法失败。Note: 我在用着Sigil https://github.com/kevin-montrose/Sigil这里。抱歉,我不太熟悉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();
}
这失败于NewDynamicMethod
, 投掷'The return Type contains some invalid type (i.e. null, ByRef)'
。这是有道理的,因为我明白在幕后WidgetMeasurer
返回一个Int32&
.
问题是,我是否可以使用一些第一方或第三方技术来发出模仿前两个示例的代码(我凭经验知道这些技术可以正常工作)?如果不是,这一限制合乎逻辑吗?
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));
}