提问者:小点点

使用ILGenerator从try和catch的内部返回值


我目前正在尝试生成一个方法,它将在try块内返回一个结果。 等价的C#代码如下所示:

public int Foo()
{
    try
    {
        return 1;
    }
    catch(Exception ex)
    {
        Console.WriteLine(ex);
        return -1;
    }
}

我知道,这显然不会抛出一个错误,但是这只是我试图做的事情的一个缩短,我可以把问题钉在try/catch。

以下是我目前得到的信息:

var method = new DynamicMethod("Foo", typeof(int), null);
var methodIL = method.GetILGenerator();

var exBlock = methodIL.BeginExceptionBlock();

methodIL.Emit(OpCodes.Ldc_I4_1);
methodIL.Emit(OpCodes.Stloc_0);
methodIL.Emit(OpCodes.Leave_S, exBlock);

methodIL.BeginCatchBlock(typeof(Exception));

methodIL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

methodIL.Emit(OpCodes.Ldc_I4_M1);
methodIL.Emit(OpCodes.Stloc_0);
methodIL.Emit(OpCodes.Leave_S, exBlock);

methodIL.EndExceptionBlock();

methodIL.Emit(OpCodes.Ldloc_0);
methodIL.Emit(OpCodes.Ret);

var foo = (Func<int>)method.CreateDelegate(typeof(Func<int>));

Console.WriteLine(foo.Invoke());

我几乎直接从Sharplab.io获得了IL。

但是,此方法会向我抛出一个异常:

System.InvalidProgramException:“公共语言运行库检测到无效程序。”

据我所知,这说明我搞砸了情报系统。


共1个答案

匿名用户

您必须调用ILGenerator.declareLocal()方法来声明要与hopcodes.ldloc_0opcodes.stloc_0一起使用的局部变量。

只需添加:methodil.DeclareLocal(typeof(int));