4

我有一个应用程序,其中我有一个采用 PropertyInfo 参数的方法,并且想从 IL 调用此方法。例如,对于采用 MethodInfo 的类似方法,我可以创建一个采用RuntimeMethodHandle的中间方法并使用GetMethodFromHandle。然后 IL 可以使用Ldtoken来传递句柄。

但是,似乎没有属性的等效元数据标记。我可以理解为什么会出现这种情况(因为属性实际上只是一种将方法捆绑在一起的方式,并且从不从 IL 中“调用”),但是肯定有与类型相关联的属性元数据。我可以在 Emit-time 访问这个属性元数据,所以我想要一种能够直接传递它的方法,而不必在运行时通过名称求助于 Reflection(即向 GetProperty 发出 Reflection 调用,获取一个将在运行时。)有没有办法做到这一点?


根据评论中的要求,这是应用程序:

我正在创建一个适配器类,它通过bool this[int index]属性将属性引用作为其组件位公开。我的应用程序将 PLC 代码编译为 .NET 程序集,因此我正在尝试创建诊断访问器,该访问器近似于 PLC 提供的简单按位访问(您在其中写入MyTag.2以指示 tag 的第 2 位MyTag。)此语法不能用于由 C# 消耗,但这PLC.GetBits().MyTag[2]是一个合理的近似值。

我最初的方法是使用 PropertyInfo 实现的(这就是我遇到这个问题的方式),但我当然可以通过将 PropertyInfo 中的适用元数据作为多个参数传递来解决它。我主要只是好奇是否可以直接传递 PropertyInfo,因为我以前从未遇到过这种情况。

4

2 回答 2

4

不,我不认为你可以。我之所以这么说,部分是因为熟悉该 API,部分是因为ExpressionC# 编译器中的编译器在引用 a 时仍然使用反射PropertyInfo,但在引用类型和方法时使用更直接的方法 ( ldtokenetc)(例如,getter /二传手)。我怀疑如果它存在的话,C# 编译器团队会使用它。

然而,在最常见的 IL-emit 场景中,没有必要传递一个PropertyInfo. 选项:

  • 用于MethodBase获取 getter 或 setter(可以通过令牌获取方法),并通过名称推断属性(不是 100% 稳健,但通常应该可以工作)
  • 改为传递名称(ldstr)
于 2012-11-18T16:16:05.470 回答
3

参考Ecma-335 , Partition I, 8.10.3属性和事件继承

从根本上说,属性和事件是元数据的构造,旨在供以 CLI 为目标的工具使用,并且不受 VES 本身的直接支持。因此,确定名称隐藏、继承等规则是源语言编译器和反射库(参见第 IV 部分 - 内核包)的工作。源编译器应生成直接访问由事件和属性命名的方法的 CIL,而不是事件或属性本身。

Ecma-335,Partition I,8.11.3属性定义

属性定义始终是接口定义或类定义的一部分。属性定义的名称和值的范围是包含该属性定义的类型。CTS 要求构成该属性的方法契约应与方法实现相匹配,就像任何其他方法契约一样。没有与 properties 相关的 CIL 指令,只有元数据。

于 2013-05-04T23:39:18.420 回答