ILGenerator.BeginFaultBlock Method

Definition

Begins an exception fault block in the Microsoft intermediate language (MSIL) stream.

C#
public abstract void BeginFaultBlock();
C#
public virtual void BeginFaultBlock();

Exceptions

The MSIL being generated is not currently in an exception block.

-or-

This ILGenerator belongs to a DynamicMethod.

Examples

The following code sample illustrates the use of BeginFaultBlock.

C#
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Security.Permissions;

public class ILGenerator_BeginFaultBlock
{
   public static Type AddType()
   {
      // Create an assembly.
      AssemblyName myAssemblyName = new AssemblyName();
      myAssemblyName.Name = "AdderExceptionAsm";

      // Create dynamic assembly.
      AppDomain myAppDomain = Thread.GetDomain();
      AssemblyBuilder myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName,
         AssemblyBuilderAccess.Run);

      // Create a dynamic module.
      ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("AdderExceptionMod");
      TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("Adder");
      Type[] myAdderParams = new Type[] {typeof(int), typeof(int)};

      // Method to add two numbers.
      MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("DoAdd",MethodAttributes.Public |
         MethodAttributes.Static,typeof(int),myAdderParams);
      ILGenerator myAdderIL = myMethodBuilder.GetILGenerator();

      // Create constructor.
      ConstructorInfo myConstructorInfo = typeof(OverflowException).GetConstructor(
         new Type[]{typeof(string)});
      MethodInfo myExToStrMI = typeof(OverflowException).GetMethod("ToString");
      MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine",new Type[]
         {typeof(string),typeof(object)});

      // Declare local variable.
      LocalBuilder myLocalBuilder1 = myAdderIL.DeclareLocal(typeof(int));
      LocalBuilder myLocalBuilder2 = myAdderIL.DeclareLocal(typeof(OverflowException));

      // Define label.
      Label myFailedLabel = myAdderIL.DefineLabel();
      Label myEndOfMethodLabel = myAdderIL.DefineLabel();

      // Begin exception block.
      Label myLabel = myAdderIL.BeginExceptionBlock();

      myAdderIL.Emit(OpCodes.Ldarg_0);
      myAdderIL.Emit(OpCodes.Ldc_I4_S, 10);
      myAdderIL.Emit(OpCodes.Bgt_S, myFailedLabel);

      myAdderIL.Emit(OpCodes.Ldarg_1);
      myAdderIL.Emit(OpCodes.Ldc_I4_S, 10);
      myAdderIL.Emit(OpCodes.Bgt_S, myFailedLabel);

      myAdderIL.Emit(OpCodes.Ldarg_0);
      myAdderIL.Emit(OpCodes.Ldarg_1);
      myAdderIL.Emit(OpCodes.Add_Ovf_Un);
      myAdderIL.Emit(OpCodes.Stloc_S, myLocalBuilder1);
      myAdderIL.Emit(OpCodes.Br_S, myEndOfMethodLabel);

      myAdderIL.MarkLabel(myFailedLabel);
      myAdderIL.Emit(OpCodes.Ldstr, "Cannot accept values over 10 for addition.");
      myAdderIL.Emit(OpCodes.Newobj, myConstructorInfo);

      myAdderIL.Emit(OpCodes.Stloc_S, myLocalBuilder2);
      myAdderIL.Emit(OpCodes.Ldloc_S, myLocalBuilder2);

      // Call fault block.
      myAdderIL.BeginFaultBlock();
      Console.WriteLine("Fault block called.");
      //Throw exception.
      myAdderIL.ThrowException(typeof(NotSupportedException));

      // Call finally block.
      myAdderIL.BeginFinallyBlock();

      myAdderIL.Emit(OpCodes.Ldstr, "{0}");
      myAdderIL.Emit(OpCodes.Ldloc_S, myLocalBuilder2);
      myAdderIL.EmitCall(OpCodes.Callvirt, myExToStrMI, null);
      myAdderIL.EmitCall(OpCodes.Call, myWriteLineMI, null);
      myAdderIL.Emit(OpCodes.Ldc_I4_M1);
      myAdderIL.Emit(OpCodes.Stloc_S, myLocalBuilder1);

      // End exception block.
      myAdderIL.EndExceptionBlock();

      myAdderIL.MarkLabel(myEndOfMethodLabel);
      myAdderIL.Emit(OpCodes.Ldloc_S, myLocalBuilder1);
      myAdderIL.Emit(OpCodes.Ret);

      return myTypeBuilder.CreateType();
   }
   
   public static void Main()
   {
      Type myAddType = AddType();
      object myObject1 = Activator.CreateInstance(myAddType);
      object[] myObject2 = new object[]{11,12};

      // Invoke member.
      myAddType.InvokeMember("DoAdd",BindingFlags.InvokeMethod,null,myObject1,myObject2);
   }
}

Remarks

If the current ILGenerator is associated with a DynamicMethod object, emitting exception fault blocks is not supported. DynamicILInfo can be used to construct a dynamic method that uses exception fault blocks.

Applies to

Product Versions
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9, 10
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0 (package-provided), 2.1