从ILGenerator尝试捕获的内部返回一个值

问题描述 投票:0回答:1

我目前正在尝试生成一种方法,该方法将在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:'公共语言运行时检测到无效程序。'

据我所知,表明我以某种方式弄乱了IL。

c# try-catch cil ilgenerator
1个回答
0
投票

您必须调用IlGenerator.DeclareLocal() Method来声明要与OpCodes.Ldloc_0OpCodes.Stloc_0一起使用的局部变量。

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

© www.soinside.com 2019 - 2024. All rights reserved.