如何发出返回引用的动态方法?

2024-03-23

我正在浏览 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));
}

我不知道为什么 DynamicMethod 存在这种限制,但以下内容对我有用。一个区别是我们手动定义我们自己的动态装配。另一个区别是,由于这是单独组装,Widget需要是公共的(或者如果您适当地命名动态程序集,则可以在父程序集上使用InternalsVisibleTo)。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何发出返回引用的动态方法? 的相关文章

随机推荐

  • Django 使用 ManytoMany 作为外键

    我正在尝试使用多对多关系作为另一个表的外键 但我不确定这是否可能 考虑以下模型 from django db import models class Attribute models Model name models CharField
  • 通过类的java sql连接

    我有以下代码 import java sql import java net public class binsz public void dbConnect String db connect string String username
  • 带数据触发器的 WPF 动画

    我有一个矩形 我正在为其背景颜色设置动画 每次特定数字上升时 它都应该变为绿色 下跌时呈红色 如果数字一段时间内没有变化 它会慢慢淡回默认颜色 因此 动画非常快速地将背景从灰色变为红色 然后需要几秒钟的时间才能淡出回灰色 我已添加为 Dat
  • 如何在 Xcode 4 中从断点操作打印字符串值?

    我有一个断点操作 并且正在使用下拉列表中的 日志 选项 我想打印出字符串 摘要 值 我正在这样做 the person name is p name 但这会打印内存地址 我可以切换到调试器命令选项并执行以下操作 po f name 但后来我
  • 如何创建不安全的 jupyter 服务器

    Jupyter 只允许从本地主机访问 除非我做了一些额外的安全工作 我正在运行我的服务器 以便它只能在本地网络上访问 任何有权访问的人都与本地主机具有相同的可信度 如何设置没有额外安全功能的 jupyter 笔记本服务器 根据您的问题 我希
  • HTML5 视频控件不起作用

    我做了很多研究 尽管有些问题 评论确实为我指明了正确的方向 但我仍然停滞不前 摘要 HTML5 视频显示控件 但无法单击 当你浏览它们时 它们就会消失 您无法单击暂停 播放 静音等任何操作 请帮我弄清楚发生了什么事 该网站是www inno
  • OpenCV 中的 Matlab Conv2 等效项

    我一直在尝试使用 OpenCV 对 2D 矩阵进行卷积 我实际上经历过这段代码http blog timmlinder com 2011 07 opencv equivalent to matlabs conv2 function resp
  • 类似热图的图,但适用于 seaborn 中的分类变量

    同样的问题类似热图的图 但适用于分类变量 https stackoverflow com questions 12998372但使用 python 和 seaborn 而不是 R 假设我有以下数据框 df pd DataFrame John
  • Gecko 清除缓存历史记录和 cookie

    帮助 我用GeckoFx Windows 10 0 0 6对于浏览器和xulrunner 10 0 en US win32 Visual Studio 2010 c 一切正常 但我需要清除 Firefox 中的所有历史记录 工具 gt gt
  • 为什么 OpenMP SIMD 指令会降低性能?

    我正在学习如何在 OpenMP Fortran 中使用 SIMD 指令 我 写了简单的代码 program loop implicit none integer i j real 8 x x 0 0 do i 1 10000 do j 1
  • 将 Spring boot 与 Elasticsearch 集成的最佳方式

    我是 Elasticsearch 的新手 我们正在使用 Elasticsearch 构建 Spring boot 应用程序 目前 我们必须使用 Spring Boot 2 1 3 RELEASE 但我们可以使用最新的稳定 Elastic s
  • ESP8266 NodeMCU 堆内存不足

    我正在尝试通过从我的笔记本电脑发送 POST 使用 node js 来使用 ESP8266 01 来切换 LED 我现在遇到内存问题 因为每当我发送 POST 请求时 ESP 中使用的内存就会增加 而堆内存会减少 并且当没有剩余内存时它会崩
  • 如何在Python中将十六进制字符串转换为字节?

    我有一个很长的十六进制字符串 表示一系列不同类型的值 我需要将此十六进制字符串转换为bytes or bytearray这样我就可以从原始数据中提取每个值 我怎样才能做到这一点 例如 字符串 ab 应该转换为字节b xab 或等效的字节数组
  • 创建圆形条形图

    我正在尝试使用我的数据创建圆形条形图 但我什至无法组织数据框来做到这一点 我对来自 3 个不同年份 名为 Campana 的列 和来自一个省的 4 个地区 名为 zona 的列 的 121 个种子进行了分析 我想制作一个如图所示的图表 使用
  • Angular 6:获取对 ng-container 标签内使用 *ngFor 创建的组件的引用

    我使用 ng container 迭代列表并创建组件
  • 关于在 SQL Server 中实现审计表的建议?

    我过去使用的一种简单方法基本上只是创建第二个表 其结构反映了我想要审核的表 然后在主表上创建一个更新 删除触发器 在更新 删除记录之前 当前状态通过触发器保存到审计表中 审计表中的数据虽然有效 但并不是最有用或最容易报告的 我想知道是否有人
  • 无法使用 C# 连接到密码加密的 MS Access 2016 数据库

    当我尝试连接到 MS Access 2016 数据库时 它无需密码即可完美连接 但是当我在使用密码加密后尝试连接到同一数据库时 出现以下错误 无法打开数据库 它可能不是您的应用程序识别的数据库 或者文件可能已损坏 我不知道我应该做什么 我的
  • 带有auto的initializer_list包含多个表达式

    相当简单的问题 auto x11 1 2 3 4 auto x1 1 2 3 4 auto x22 1 0 2 25 3 5 auto x2 1 0 2 25 3 5 据我了解 这里应该没有什么区别 或不 但是 使用 llvm clang
  • OpenJPA 2.1.1 - 找不到元素“persistence”的声明

    我刚刚下载了http www apache org dyn closer cgi openejb 4 0 0 beta 1 apache tomee 1 0 0 beta 1 webprofile zip http www apache o
  • 如何发出返回引用的动态方法?

    我正在浏览 ref 返回的来龙去脉 并且在发出由 ref 返回的动态方法时遇到问题 手工制作的 lambda 表达式和现有方法按预期工作 class Widget public int Length delegate ref int Wid