. NET (C #): How to handle exceptions created by Emit

Source: Internet
Author: User
Tags emit finally block

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!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.