通过元数据令牌访问PropertyInfo以便在IL中使用?

时间:2012-11-18 15:54:52

标签: c# .net reflection reflection.emit il

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

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


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

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

我的原始方法是使用PropertyInfo实现的(这是我遇到此问题的方法),但我当然可以通过将PropertyInfo中的适用元数据作为多个参数传递来解决它。我主要只是想知道是否有可能直接传递PropertyInfo,因为我之前从未遇到过这种情况。

2 个答案:

答案 0 :(得分:4)

不,我认为你不能。我之所以这么说是因为熟悉该API,部分原因是C#编译器中的Expression编译器在引用PropertyInfo时仍使用反射,但使用了更直接的方法({{1}引用类型和方法时(例如,getter / setter)。我怀疑C#编译器团队会在它存在的情况下使用它。

但是,在大多数常见的IL-emit场景中,没有必要传递ldtoken。选项:

  • 使用PropertyInfo获取getter或setter(方法可以通过令牌获取),并按名称推断属性(不是100%健壮,但通常应该有效)
  • 传递名称(ldstr)

答案 1 :(得分:3)

请参阅Ecma-335,分区I,8.10.3 属性和事件继承

  

从根本上说,属性和事件是供工具使用的元数据的结构   目标CLI和不受VES本身直接支持。因此,这是工作的   源语言编译器和反射库(参见Partition IV - Kernel Package)来   确定名称隐藏,继承等规则。源编译器应生成   直接访问由事件和属性命名的方法的CIL,而不是事件或   物业本身。

Ecma-335,分区I,8.11.3 属性定义

  

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