ILGenerator.BeginFinallyBlock 方法

定义

在 Microsoft 中间语言 (MSIL) 指令流中开始一个 Finally 块。

public:
 virtual void BeginFinallyBlock();
public:
 abstract void BeginFinallyBlock();
public virtual void BeginFinallyBlock ();
public abstract void BeginFinallyBlock ();
abstract member BeginFinallyBlock : unit -> unit
override this.BeginFinallyBlock : unit -> unit
abstract member BeginFinallyBlock : unit -> unit
Public Overridable Sub BeginFinallyBlock ()
Public MustOverride Sub BeginFinallyBlock ()

例外

生成的 MSIL 当前不在异常块中。

示例

下面的代码示例演示如何使用 BeginFinallyBlock

using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;

public ref class ILGenerator_BeginFinallyBlock
{
public:
   static Type^ AddType()
   {
      // Create an assembly.
      AssemblyName^ myAssemblyName = gcnew 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" );
      array<Type^>^adderParams = {int::typeid,int::typeid};

      // Define method to add two numbers.
      MethodBuilder^ myMethodBuilder = myTypeBuilder->DefineMethod( "DoAdd", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), int::typeid, adderParams );
      ILGenerator^ myAdderIL = myMethodBuilder->GetILGenerator();

      // Create constructor.
      array<Type^>^type1 = {String::typeid};
      ConstructorInfo^ myConstructorInfo = OverflowException::typeid->GetConstructor( type1 );
      MethodInfo^ myExToStrMI = OverflowException::typeid->GetMethod( "ToString" );
      array<Type^>^type2 = {String::typeid,Object::typeid};
      MethodInfo^ myWriteLineMI = Console::typeid->GetMethod( "WriteLine", type2 );

      // Declare local variable.
      LocalBuilder^ myLocalBuilder1 = myAdderIL->DeclareLocal( int::typeid );
      LocalBuilder^ myLocalBuilder2 = myAdderIL->DeclareLocal( OverflowException::typeid );

      // 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 add." );
      myAdderIL->Emit( OpCodes::Newobj, myConstructorInfo );
      myAdderIL->Emit( OpCodes::Stloc_S, myLocalBuilder2 );
      myAdderIL->Emit( OpCodes::Ldloc_S, myLocalBuilder2 );

      // Throw the exception.
      myAdderIL->ThrowException( OverflowException::typeid );

      // Call 'BeginExceptFilterBlock'.
      myAdderIL->BeginExceptFilterBlock();
      myAdderIL->EmitWriteLine( "Except filter block called." );

      // Call catch block.
      myAdderIL->BeginCatchBlock( nullptr );

      // Call other catch block.
      myAdderIL->BeginCatchBlock( OverflowException::typeid );
      myAdderIL->Emit( OpCodes::Ldstr, "{0}" );
      myAdderIL->Emit( OpCodes::Ldloc_S, myLocalBuilder2 );
      myAdderIL->EmitCall( OpCodes::Callvirt, myExToStrMI, nullptr );
      myAdderIL->EmitCall( OpCodes::Call, myWriteLineMI, nullptr );
      myAdderIL->Emit( OpCodes::Ldc_I4_M1 );
      myAdderIL->Emit( OpCodes::Stloc_S, myLocalBuilder1 );

      // Call finally block.
      myAdderIL->BeginFinallyBlock();
      myAdderIL->EmitWriteLine( "Finally block called." );

      // End the exception block.
      myAdderIL->EndExceptionBlock();
      myAdderIL->MarkLabel( myEndOfMethodLabel );
      myAdderIL->Emit( OpCodes::Ldloc_S, myLocalBuilder1 );
      myAdderIL->Emit( OpCodes::Ret );
      return myTypeBuilder->CreateType();
   }
};

int main()
{
   Type^ myAddType = ILGenerator_BeginFinallyBlock::AddType();
   Object^ myObject1 = Activator::CreateInstance( myAddType );
   array<Object^>^myObject2 = {15,15};
   myAddType->InvokeMember( "DoAdd", BindingFlags::InvokeMethod, nullptr, myObject1, myObject2 );
}
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Security.Permissions;

public class ILGenerator_BeginFinallyBlock
{
   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[] adderParams = new Type[] {typeof(int), typeof(int)};

      // Define method to add two numbers.
      MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("DoAdd",MethodAttributes.Public |
         MethodAttributes.Static,typeof(int),adderParams);
      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 add.");
      myAdderIL.Emit(OpCodes.Newobj, myConstructorInfo);

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

      // Throw the exception.
      myAdderIL.ThrowException(typeof(OverflowException));

      // Call 'BeginExceptFilterBlock'.
      myAdderIL.BeginExceptFilterBlock();
      myAdderIL.EmitWriteLine("Except filter block called.");

      // Call catch block.
      myAdderIL.BeginCatchBlock(null);

      // Call other catch block.
      myAdderIL.BeginCatchBlock(typeof(OverflowException));

      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);

      // Call finally block.
      myAdderIL.BeginFinallyBlock();
      myAdderIL.EmitWriteLine("Finally block called.");

      // End the 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[]{15,15};
      myAddType.InvokeMember("DoAdd", BindingFlags.InvokeMethod,
         null, myObject1, myObject2);
   }
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Security.Permissions

Public Class ILGenerator_BeginFinallyBlock
   Public Shared Function AddType() As Type
      ' Create an assembly.
      Dim myAssemblyName As New AssemblyName()
      myAssemblyName.Name = "AdderExceptionAsm"

      ' Create dynamic assembly.
      Dim myAppDomain As AppDomain = Thread.GetDomain()
      Dim myAssemblyBuilder As AssemblyBuilder = _
            myAppDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Run)

      ' Create a dynamic module.
      Dim myModuleBuilder As ModuleBuilder = _
            myAssemblyBuilder.DefineDynamicModule("AdderExceptionMod")
      Dim myTypeBuilder As TypeBuilder = myModuleBuilder.DefineType("Adder")
      Dim adderParams() As Type = {GetType(Integer), GetType(Integer)}

      ' Define method to add two numbers.
      Dim myMethodBuilder As MethodBuilder = _
            myTypeBuilder.DefineMethod("DoAdd", MethodAttributes.Public Or _
            MethodAttributes.Static, GetType(Integer), adderParams)
      Dim myAdderIL As ILGenerator = myMethodBuilder.GetILGenerator()

      ' Create constructor.
      Dim myConstructorInfo As ConstructorInfo = _
            GetType(OverflowException).GetConstructor(New Type() {GetType(String)})
      Dim myExToStrMI As MethodInfo = GetType(OverflowException).GetMethod("ToString")
      Dim myWriteLineMI As MethodInfo = _
            GetType(Console).GetMethod("WriteLine", New Type() {GetType(String), GetType(Object)})

      ' Declare local variable.
      Dim myLocalBuilder1 As LocalBuilder = myAdderIL.DeclareLocal(GetType(Integer))
      Dim myLocalBuilder2 As LocalBuilder = myAdderIL.DeclareLocal(GetType(OverflowException))

      ' Define label.
      Dim myFailedLabel As Label = myAdderIL.DefineLabel()
      Dim myEndOfMethodLabel As Label = myAdderIL.DefineLabel()

      ' Begin exception block.
      Dim myLabel As Label = 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 add.")
      myAdderIL.Emit(OpCodes.Newobj, myConstructorInfo)

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

      ' Throw the exception.
      myAdderIL.ThrowException(GetType(OverflowException))

      ' Call 'BeginExceptFilterBlock'.
      myAdderIL.BeginExceptFilterBlock()
      myAdderIL.EmitWriteLine("Except filter block called.")

      ' Call catch block.
      myAdderIL.BeginCatchBlock(Nothing)

      ' Call other catch block.
      myAdderIL.BeginCatchBlock(GetType(OverflowException))

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

      ' Call finally block.
      myAdderIL.BeginFinallyBlock()
      myAdderIL.EmitWriteLine("Finally block called.")

      ' End the exception block.
      myAdderIL.EndExceptionBlock()

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

      Return myTypeBuilder.CreateType()
   End Function 'AddType

   <PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
   Public Shared Sub Main()
      Dim myAddType As Type = AddType()
      Dim myObject1 As Object = Activator.CreateInstance(myAddType)
      Dim myObject2() As Object = {15, 15}
      myAddType.InvokeMember("DoAdd", BindingFlags.InvokeMethod, Nothing, myObject1, myObject2)
   End Sub
End Class

适用于