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);
You can use the out keyword in two contexts: As a parameter modifier, which lets you pass an argument to a method by reference rather than by value. In generic type parameter declarations for interfaces and delegates, which specifies that a type parameter is covariant.
An out
argument is just a ref
argument with the OutAttribute
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.
ldarg.0
ldnull
stind.ref
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With