public BeginExceptionBlock ( ) : System.Reflection.Emit.Label | ||
return | System.Reflection.Emit.Label |
ILGenerator generator = methodBuilder.GetILGenerator(); Label tryBlock = generator.BeginExceptionBlock(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); generator.Emit(OpCodes.Pop); generator.BeginCatchBlock(typeof(Exception)); generator.Emit(OpCodes.Ldstr, "An error occurred: {0}"); generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Callvirt, typeof(Exception).GetMethod("get_Message")); generator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) })); generator.Emit(OpCodes.Pop); generator.EndExceptionBlock();
var methodBuilder = typeBuilder.DefineMethod("Divide", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new[] { typeof(int), typeof(int) }); var generator = methodBuilder.GetILGenerator(); var tryStart = generator.BeginExceptionBlock(); var result = generator.DeclareLocal(typeof(int)); // Always assign block scopes to temporaries, if you have any variables at all. generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Div); generator.Emit(OpCodes.Stloc, result); var tryEnd = generator.DefineLabel(); generator.Emit(OpCodes.Br_S, tryEnd); var catchEx = generator.BeginCatchBlock(typeof(DivideByZeroException)); generator.Emit(OpCodes.Pop); generator.Emit(OpCodes.Ldc_I4_0); var endTry = generator.DefineLabel(); generator.Emit(OpCodes.Br_S, endTry); generator.MarkLabel(tryEnd); generator.Emit(OpCodes.Ldloc, result); generator.Emit(OpCodes.Ret); generator.MarkLabel(catchEx); generator.Emit(OpCodes.Pop); generator.Emit(OpCodes.Ldnull); generator.Emit(OpCodes.Throw); generator.MarkLabel(endTry); generator.EndExceptionBlock();In this example, we define a new method called Divide using the DefineMethod method of a TypeBuilder object. Within the method, we create a new try block by calling the BeginExceptionBlock method and storing the resulting label in a variable. Within the try block, we calculate the result of dividing two arguments and store it in a local variable. We then define a label and emit an unconditional branch to it. After the try block, we define a catch block by calling the BeginCatchBlock method and passing in the type of exception we want to catch (in this case, DivideByZeroException). Within the catch block, we simply emit IL code to return 0. Finally, we define another label and emit a branch to it. We then emit IL code to load the result variable and return it. If an exception was caught, we skip this code entirely and instead throw the caught exception. Overall, BeginExceptionBlock is a useful method for generating IL code that handles exceptions in a structured way. It is part of the System.Reflection.Emit namespace, which is included in the .NET Framework Class Library.