DynamicMethod 和输出参数?
如何为具有 out
参数的委托定义 DynamicMethod,如下所示?
public delegate void TestDelegate(out Action a);
假设我只是想要一个在调用该方法时将 a
参数设置为 null
的方法。
请注意,我知道处理此问题的更好方法可能是使该方法返回 Action 委托,但这只是较大项目的简化部分,并且相关方法已经返回值,除了它之外,我还需要处理 out
参数,因此出现了问题。
我尝试了这个:
using System;
using System.Text;
using System.Reflection.Emit;
namespace ConsoleApplication8
{
public class Program
{
public delegate void TestDelegate(out Action a);
static void Main(String[] args)
{
var method = new DynamicMethod("TestMethod", typeof(void),
new Type[] { typeof(Action).MakeByRefType() });
var il = method.GetILGenerator();
// a = null;
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Starg, 0);
// return
il.Emit(OpCodes.Ret);
var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate));
Action a;
del(out a);
}
}
}
但是,我得到了这个:
VerificationException was unhandled:
Operation could destabilize the runtime.
在 del(out a);
行。
请注意,如果我注释掉在堆栈上加载 null 的两行并尝试将其存储到参数中,则该方法将毫无异常地运行。
编辑:这是最好的方法吗?
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stind_Ref);
How do I define a DynamicMethod for a delegate that has an out
-parameter, like this?
public delegate void TestDelegate(out Action a);
Let's say I simply want a method that sets the a
argument to null
when I call the method.
Note that I know that a probably better way to handle this would be to make the method return the Action
delegate, but this is just a simplified part of a larger project, and the method in question already returns a value, I need to handle the out
parameter in addition to it, hence the question.
I tried this:
using System;
using System.Text;
using System.Reflection.Emit;
namespace ConsoleApplication8
{
public class Program
{
public delegate void TestDelegate(out Action a);
static void Main(String[] args)
{
var method = new DynamicMethod("TestMethod", typeof(void),
new Type[] { typeof(Action).MakeByRefType() });
var il = method.GetILGenerator();
// a = null;
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Starg, 0);
// return
il.Emit(OpCodes.Ret);
var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate));
Action a;
del(out a);
}
}
}
However, I get this:
VerificationException was unhandled:
Operation could destabilize the runtime.
on the del(out a);
line.
Note that if I comment out the two lines that load a null on the stack and attempts to store it into the argument, the method runs without exceptions.
Edit: Is this the best approach?
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stind_Ref);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
out
参数只是一个带有OutAttribute
应用于参数。要存储到 by-ref 参数,您需要使用
stind
操作码,因为参数本身是指向对象实际位置的托管指针。An
out
argument is just aref
argument with theOutAttribute
applied to the parameter.To store to the by-ref argument, you need to use the
stind
opcode, because the argument itself is a managed pointer to the object's actual location.