C# 在投掷后,发电机发出树叶
我正在通过ilgenerator生成一个方法,我遇到了一个问题C# 在投掷后,发电机发出树叶,c#,cil,ilgenerator,C#,Cil,Ilgenerator,我正在通过ilgenerator生成一个方法,我遇到了一个问题IlGenerator.BeginCatchBlock()强制离开,在这种情况下,它是无法访问的指令 using System; using System.Reflection; using System.Reflection.Emit; using System.Threading; namespace Stack { class Program { static void Main(string[]
IlGenerator.BeginCatchBlock()
强制离开,在这种情况下,它是无法访问的指令
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace Stack
{
class Program
{
static void Main(string[] args)
{
var asmName = new AssemblyName("Test");
var domain = Thread.GetDomain();
var assembly = domain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
var module = assembly.DefineDynamicModule("MyModule", "Test.dll", true);
var type = module.DefineType("MyType");
var method = type.DefineMethod("MyMethod", MethodAttributes.Public);
var ilg = method.GetILGenerator();
ilg.BeginExceptionBlock();
ilg.ThrowException(typeof(Exception));
ilg.BeginCatchBlock(typeof(Exception));
ilg.Emit(OpCodes.Pop);
ilg.EndExceptionBlock();
ilg.Emit(OpCodes.Ret);
type.CreateType();
assembly.Save("test.dll");
}
}
}
实际上,输出就像
.method public instance void MyMethod () cil managed
{
.maxstack 1
.try
{
IL_0000: newobj instance void [mscorlib]System.Exception::.ctor()
IL_0005: throw
IL_0006: leave IL_0011
} // end .try
catch [mscorlib]System.Exception
{
IL_000b: pop
IL_000c: leave IL_0011
} // end handler
IL_0011: ret
}
我没想到会把IL_0011留在。试试block。PEVerify没有显示错误。只是出于好奇,为什么会出现问题?我了解到,
IL_0006:leave IL_0011
是无法访问的,但它似乎足够无害?请查看参考源。与错误处理相关的ILGenerator
功能本身会发出一些操作码,对此无能为力。可靠地检测无法到达的代码会减少停机问题。在这种情况下,任何一个好的编译器都可以看到指令是不可访问的,但是Reflection.Emit
不是一个编译器,因此它总是在块的末尾发出leave
,而无需更努力地尝试,或者让您选择忽略它,因为您知道得更好。出于同样的原因,PEVerify没有抱怨,因为无法访问的IL代码不是错误,它只是多余的。你会发现这种“次优”的IL实际上很常见,因为它更简单,JIT编译器应该可以弥补这个不足。你讲了一个故事:你遇到了一个问题,你写了一些代码,它做了一些你意想不到的事情。这是一个非常好的故事,但这里没有我们可以回答的问题。你的问题是什么?如果你隐含的问题是“我应该怎么做?”那么我的建议是:当你的期望与之矛盾时,学会接受你的期望是错误的,并调整它们以符合现实。如果这不是你的问题,那就实际问一个问题。