Return 使用 ILGenerator 的 try 和 catch 内部的值
Return a value from the inside of a try and catch with an ILGenerator
我目前正在尝试生成一种方法,该方法会 return 在 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: 'Common Language Runtime detected an invalid program.'
据我所知,这表明我以某种方式搞砸了 IL。
您必须调用 IlGenerator.DeclareLocal() Method 来声明要与 OpCodes.Ldloc_0
和 OpCodes.Stloc_0
.
一起使用的局部变量
只需添加:
methodIL.DeclareLocal(typeof(int));
我目前正在尝试生成一种方法,该方法会 return 在 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: 'Common Language Runtime detected an invalid program.'
据我所知,这表明我以某种方式搞砸了 IL。
您必须调用 IlGenerator.DeclareLocal() Method 来声明要与 OpCodes.Ldloc_0
和 OpCodes.Stloc_0
.
只需添加:
methodIL.DeclareLocal(typeof(int));