使用 IL Emit 加载 ParameterInfo [英] Loading a ParameterInfo using IL Emit

查看:46
本文介绍了使用 IL Emit 加载 ParameterInfo的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用 使用 IL Emit 作为指导调用现有对象的方法,我已经可以做任何有问题的事情.现在,我向参数添加了一个属性,我想加载该特定参数的属性,以便我可以调用该属性内的方法.

I am currently using Calling a method of existing object using IL Emit as a guide, and I can already do whatever is asked in question. Now, I have an attribute added to a parameter and I want to load that particular parameter's attribute so that I can call a method inside that attribute.

我知道这可以通过加载 MethodInfo 然后获取 ParameterInfo 然后获取该 ParameterInfo 在 IL 中的属性来完成;我只是想避免写那么多 IL.

I know it can be done by loading the MethodInfo and then getting the ParameterInfo and then getting attribute of that ParameterInfo in IL; I am simply trying to avoid writing that much IL.

有没有办法像链接帖子中提到的那样在 IL 中加载参数的属性?

Is there a way to load a parameter's attribute in IL just like it is mentioned in the linked post?

我有一个像

Method([Attr] int Parameter)

我想加载一个方法,它是 Attr 的一部分.我只是希望我可以将 ParameterInfo(使用 MethodInfo.GetParameters() 获得)直接加载到堆栈上.事实证明,LdToken 并不允许放入 ParameterInfo.我能想到的唯一其他方法是加载 MethodInfo(LdToken 支持),然后在 IL 中使用 GetParameters() 来获取参数数组,然后在 IL 中逐个循环它们以获取每个参数的 Attribute(使用 .GetCustomAttribute(Type)),然后调用该属性的方法.请注意,我不必获取属性的字段,我需要对该属性调用一个方法.

and I want to load a method which is part of the Attr. I was just hoping I could load ParameterInfo (obtained using MethodInfo.GetParameters()) directly onto the stack. Turns out, LdToken doesn't really allow putting ParameterInfo. Only other way I can think of doing this is to load MethodInfo (LdToken supports that) and then use GetParameters() in IL to get an array of Parameters and then loop through them in IL one by one to get each one's Attribute (using .GetCustomAttribute(Type)) and then call the method on that attribute. Note that I don't have to get a field of an attribute, I need to call a method on that attribute.

推荐答案

为了将来参考,我实际上继续使用 IL 加载 ParameterInfo.Marc 的解决方案很好,但在基于参数的属性数量增加后,它很快变得不可行.我们计划使用属性来包含一些特定于状态的信息,我们将不得不使用来自类型外部的大量反射来查找并为字段分配正确的属性.总的来说,处理它会变得非常忙碌.

For future reference, I actually went ahead and loaded ParameterInfo using IL only. Marc's solution was good, but it quickly became infeasible after the number of parameter based attributes increased. We plan to use attributes to contain some state specific information, we would have to use a ton of reflection from outside the type to find and assign correct attribute to the field. Overall, it would have become quite hectic to deal with it.

使用IL加载ParameterInfo

IL.Emit(OpCodes.Ldtoken, Method); // Method is MethodInfo as we can't use GetParameters with MethodBuilder
IL.Emit(OpCodes.Call, typeof(MethodBase).GetMethod(nameof(MethodBase.GetMethodFromHandle), new[] { typeof(RuntimeMethodHandle) }));
IL.Emit(OpCodes.Callvirt, typeof(MethodInfo).GetMethod(nameof(MethodInfo.GetParameters)));
var ILparameters = IL.DeclareLocal(typeof(ParameterInfo[]));
IL.Emit(OpCodes.Stloc, ILparameters);

ParameterInfo 加载到堆栈上,然后将其存储到名为 ILparametersLocalBuilder 中.请注意,它是一个数组.然后可以像

that loads ParameterInfo onto stack and then stores it into a LocalBuilder called ILparameters. Note that it is an array. Items of this array can then be accessed like

IL.Emit(OpCodes.Ldloc, ILparameters);
IL.Emit(OpCodes.Ldc_I4, Number); // Replace with Ldc_I4_x if number < 8
IL.Emit(OpCodes.Ldelem_Ref);

我更喜欢为两个代码片段创建两个辅助函数.效果很好.

I prefer to create two helper functions for the two code pieces. It works pretty well.

这篇关于使用 IL Emit 加载 ParameterInfo的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆