Directory
Emit exception handling process
Display the Message attribute of the Exception object
Returned directory
Emit exception handling process
Let's look at this C # Exception Handling Code:
Copy codeCode: static void doo (Exception e)
{
Try
{
Throw e;
}
Catch (ApplicationException ex)
{
Console. WriteLine ("Capture ApplicationException ");
}
Catch
{
Console. WriteLine ("Capture Exception ");
}
Finally
{
Console. WriteLine ("finally block ");
}
}
We will use Reflection Emit to create such a method.
In fact, the exception handling code in IL is still complicated. You can look at the IL code for exception handling under Reflector. Fortunately, the ILGenerator class provides some convenient methods to create exception handling code.
The basic routine is to use the following ILGenerator method:
BeginExceptionBlock method to start Exception Handling Code (equivalent to try ).
Later code can use Opcodes. Throw to Throw an exception or call other code that can Throw an exception.
Next, use the BeginCatchBlock method to start a Catch block. This method can specify the exception type to be caught in the catch. In addition, you need to note that when you access the catch method, there will be corresponding types of exception objects on the logical stack. You can also use Opcodes. Rethrow to throw an exception again.
The BeginFinallyBlock method starts a finally block. (You do not need to manually add Opcodes. Leave here)
After writing all the exception handling code, add the EndExceptionBlock method to end the entire exception handling code block.
Note that the method must add the ret command of IL (Opcodes. Ret) At the end, otherwise the CLR cannot run this method.
Let's look at the Code:
Copy codeThe Code is as follows: // + using System. Reflection;
// + Using System. Reflection. Emit;
Static void Main (string [] args)
{
Var dm = GetMethod ();
Dm. Invoke (null, new object [] {new ApplicationException ()});
Dm. Invoke (null, new object [] {new Exception ()});
}
Static DynamicMethod GetMethod ()
{
Var dm = new DynamicMethod ("", null, new Type [] {typeof (Exception )});
Var ilgen = dm. GetILGenerator ();
// Try {
Ilgen. BeginExceptionBlock ();
// Load the first parameter and throw
Ilgen. Emit (OpCodes. Ldarg_0 );
Ilgen. Emit (OpCodes. Throw );
Ilgen. BeginCatchBlock (typeof (ApplicationException ));
// Clear the exception object on the stack
Ilgen. Emit (OpCodes. Pop );
Ilgen. EmitWriteLine ("Capture ApplicationException ");
Ilgen. BeginCatchBlock (typeof (Exception ));
// Clear the exception object on the stack
Ilgen. Emit (OpCodes. Pop );
Ilgen. EmitWriteLine ("Capture Exception ");
Ilgen. BeginFinallyBlock ();
Ilgen. EmitWriteLine ("finally block ");
// End the entire processing block
Ilgen. EndExceptionBlock ();
Ilgen. Emit (OpCodes. Ret );
Return dm;
}
Output:
Copy codeThe Code is as follows: capture ApplicationException
Finally block
Capture Exception
Finally block
Returned directory
Display the Message attribute of the Exception object
The above Code does not display the Message attribute of the Exception object. The above mainly introduces the Emit Exception handling process. Let's take a look at how to display the Message attribute. If it is a direct output, it is certainly easy, however, if Console is used. if the WriteLine format is a string, a temporary variable must be used in the catch code block.
The following code:
Copy codeThe Code is as follows: // + using System. Reflection;
// + Using System. Reflection. Emit;
Static void Main (string [] args)
{
Var dm = GetMethod ();
Dm. Invoke (null, new object [] {new Exception ("from Mgen! ")});
}
Static DynamicMethod GetMethod ()
{
Var dm = new DynamicMethod ("", null, new Type [] {typeof (Exception )});
Var ilgen = dm. GetILGenerator ();
// Try {
Ilgen. BeginExceptionBlock ();
// Load the first parameter and throw
Ilgen. Emit (OpCodes. Ldarg_0 );
Ilgen. Emit (OpCodes. Throw );
Ilgen. BeginCatchBlock (typeof (Exception ));
// Temporary variables and required reflection Information
Var exp = ilgen. DeclareLocal (typeof (Exception ));
Var msg = typeof (Exception). GetProperty ("Message"). GetGetMethod ();
Var output = typeof (Console). GetMethod ("WriteLine", new Type [] {typeof (string), typeof (object )});
// Save the exception object to the Temporary Variable exp
Ilgen. Emit (OpCodes. Stloc, exp );
// Format string to stack
Ilgen. Emit (OpCodes. Ldstr, "error message: {0 }");
// Load temporary variables
Ilgen. Emit (OpCodes. Ldloc, exp );
// Obtain Message attributes
Ilgen. Emit (OpCodes. Callvirt, msg );
// Call Console. WriteLine with a formatted string
Ilgen. Emit (OpCodes. Call, output );
// End the entire processing block
Ilgen. EndExceptionBlock ();
Ilgen. Emit (OpCodes. Ret );
Return dm;
}
Output:
Copy codeThe Code is as follows: error message: From Mgen!