This documentation is archived and is not being maintained.

ILGenerator.ThrowException Method

Emits an instruction to throw an exception.

[Visual Basic]
Public Overridable Sub ThrowException( _
   ByVal excType As Type _
)
[C#]
public virtual void ThrowException(
 Type excType
);
[C++]
public: virtual void ThrowException(
 Type* excType
);
[JScript]
public function ThrowException(
   excType : Type
);

Parameters

excType
The class of the type of exception to throw.

Exceptions

Exception Type Condition
ArgumentException excType is not the Exception class or a derived class of Exception.

-or-

The type does not have a default constructor.

ArgumentNullException excType is a null reference (Nothing in Visual Basic).

Example

[Visual Basic, C#, C++] The following code sample demonstrates the contextual usage of ThrowException to throw an exception inside the IL of a dynamic method.

[Visual Basic] 
Imports System
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit

 _

Class ILThrowExceptionDemo
   
   
   Public Shared Function BuildAdderType() As Type
      
      Dim myDomain As AppDomain = Thread.GetDomain()
      Dim myAsmName As New AssemblyName()
      myAsmName.Name = "AdderExceptionAsm"
      Dim myAsmBldr As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
                            AssemblyBuilderAccess.Run)
      
      Dim myModBldr As ModuleBuilder = myAsmBldr.DefineDynamicModule("AdderExceptionMod")
      
      Dim myTypeBldr As TypeBuilder = myModBldr.DefineType("Adder")
      
      Dim adderParams() As Type = {GetType(Integer), GetType(Integer)}
      
      ' This method will add two numbers which are 100 or less. If either of the
      ' passed integer vales are greater than 100, it will throw an exception.
      Dim adderBldr As MethodBuilder = myTypeBldr.DefineMethod("DoAdd", _
                        MethodAttributes.Public Or MethodAttributes.Static, _
                        GetType(Integer), adderParams)
      Dim adderIL As ILGenerator = adderBldr.GetILGenerator()
      
      ' In order to successfully branch, we need to create labels
      ' representing the offset IL instruction block to branch to.
      ' These labels, when the MarkLabel(Label) method is invoked,
      ' will specify the IL instruction to branch to.
      Dim exCtorInfo As ConstructorInfo = GetType(OverflowException).GetConstructor( _
                            New Type() {GetType(String)})
      Dim exToStrMI As MethodInfo = GetType(OverflowException).GetMethod("ToString")
      Dim writeLineMI As MethodInfo = GetType(Console).GetMethod("WriteLine", _
                            New Type() {GetType(String), _
                                    GetType(Object)})
      
      Dim tmp1 As LocalBuilder = adderIL.DeclareLocal(GetType(Integer))
      Dim tmp2 As LocalBuilder = adderIL.DeclareLocal(GetType(OverflowException))
      
      Dim failed As Label = adderIL.DefineLabel()
      Dim endOfMthd As Label = adderIL.DefineLabel()
      
      ' First, load argument 0 and the integer value of "100" onto the
      ' stack. If arg0 > 100, branch to the label "failed", which is marked
      ' as the address of the block that throws an exception.

      Dim exBlock As Label = adderIL.BeginExceptionBlock()
      adderIL.Emit(OpCodes.Ldarg_0)
      adderIL.Emit(OpCodes.Ldc_I4_S, 100)
      adderIL.Emit(OpCodes.Bgt_S, failed)
      
      ' Now, check to see if argument 1 was greater than 100. If it was,
      ' branch to "failed." Otherwise, fall through and perform the addition,
      ' branching unconditionally to the instruction at the label "endOfMthd".

      adderIL.Emit(OpCodes.Ldarg_1)
      adderIL.Emit(OpCodes.Ldc_I4_S, 100)
      adderIL.Emit(OpCodes.Bgt_S, failed)
      
      adderIL.Emit(OpCodes.Ldarg_0)
      adderIL.Emit(OpCodes.Ldarg_1)
      adderIL.Emit(OpCodes.Add_Ovf_Un)
      adderIL.Emit(OpCodes.Stloc_S, tmp1)
      adderIL.Emit(OpCodes.Br_S, endOfMthd)
      
      ' If one of the arguments was greater than 100, we need to throw an
      ' exception. We'll use "OverflowException" with a customized message.
      ' First, we load our message onto the stack, and then create a new
      ' exception object using the constructor overload that accepts a

      ' string message.
      adderIL.MarkLabel(failed)
      adderIL.Emit(OpCodes.Ldstr, "Cannot accept values over 100 for add.")
      adderIL.Emit(OpCodes.Newobj, exCtorInfo)
      
      ' We're going to need to refer to that exception object later, so let's
      ' store it in a temporary variable. Since the store function pops the
      ' the value/reference off the stack, and we'll need it to throw the
      ' exception, we will subsequently load it back onto the stack as well.

      adderIL.Emit(OpCodes.Stloc_S, tmp2)
      adderIL.Emit(OpCodes.Ldloc_S, tmp2)
      
      ' Throw the exception currently atop the stack.

      adderIL.ThrowException(GetType(OverflowException))
      
      ' Start the catch block.

      adderIL.BeginCatchBlock(GetType(OverflowException))
      
      ' First, we'll load a "wrapper" string, and then perform a 
      ' late-bound call to the ToString() method of OverflowException,
      ' passing it the exception object we stored in local variable tmp2.

      adderIL.Emit(OpCodes.Ldstr, "{0}")
      adderIL.Emit(OpCodes.Ldloc_S, tmp2)
      adderIL.EmitCall(OpCodes.Callvirt, exToStrMI, Nothing)
      
      ' Now, we should have the "wrapper" string atop the stack,
      ' along with the string result of the ToString() call. All
      ' conditions are met to call WriteLine(string, object).

      adderIL.EmitCall(OpCodes.Call, writeLineMI, Nothing)
      
      ' Since our function has to return an integer value, we'll load -1 onto
      ' the stack to indicate an error, and store it in local variable tmp1.

      adderIL.Emit(OpCodes.Ldc_I4_M1)
      adderIL.Emit(OpCodes.Stloc_S, tmp1)
      
      ' End the exception handling block.

      adderIL.EndExceptionBlock()
      
      ' The end of the method. If no exception was thrown, the correct value
      ' will be saved in tmp1. If an exception was thrown, tmp1 will be equal
      ' to -1. Either way, we'll load the value of tmp1 onto the stack and return.

      adderIL.MarkLabel(endOfMthd)
      adderIL.Emit(OpCodes.Ldloc_S, tmp1)
      adderIL.Emit(OpCodes.Ret)
      
      Return myTypeBldr.CreateType()

   End Function 'BuildAdderType
    
   
   Public Shared Sub Main()
      
      Dim adderType As Type = BuildAdderType()
      
      Dim addIns As Object = Activator.CreateInstance(adderType)
      
      Dim addParams(1) As Object
      
      Console.Write("Enter an integer value: ")
      addParams(0) = CType(Convert.ToInt32(Console.ReadLine()), Object)
      
      Console.Write("Enter another integer value: ")
      addParams(1) = CType(Convert.ToInt32(Console.ReadLine()), Object)
      
      Console.WriteLine("If either integer was > 100, an exception will be thrown.")
      Console.WriteLine("---")
      
      Console.WriteLine("{0} + {1} = {2}", addParams(0), addParams(1), _
            adderType.InvokeMember("DoAdd", _
                        BindingFlags.InvokeMethod, _
                        Nothing, addIns, addParams))

   End Sub 'Main

End Class 'ILThrowExceptionDemo




[C#] 

using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;

class ILThrowExceptionDemo {

   public static Type BuildAdderType() {

      AppDomain myDomain = Thread.GetDomain();
      AssemblyName myAsmName = new AssemblyName();
      myAsmName.Name = "AdderExceptionAsm";
      AssemblyBuilder myAsmBldr = myDomain.DefineDynamicAssembly(myAsmName,
                                    AssemblyBuilderAccess.Run);

      ModuleBuilder myModBldr = myAsmBldr.DefineDynamicModule("AdderExceptionMod");

      TypeBuilder myTypeBldr = myModBldr.DefineType("Adder");

     Type[] adderParams = new Type[] {typeof(int), typeof(int)};

    // This method will add two numbers which are 100 or less. If either of the
    // passed integer vales are greater than 100, it will throw an exception.

    MethodBuilder adderBldr = myTypeBldr.DefineMethod("DoAdd",
                            MethodAttributes.Public |
                               MethodAttributes.Static,
                               typeof(int),
                               adderParams);
    ILGenerator adderIL = adderBldr.GetILGenerator();

    // representing the offset IL instruction block to branch to.
    // These labels, when the MarkLabel(Label) method is invoked,
    // will specify the IL instruction to branch to.

    ConstructorInfo exCtorInfo = typeof(OverflowException).GetConstructor(
                                new Type[]
                                {typeof(string)});
    MethodInfo exToStrMI = typeof(OverflowException).GetMethod("ToString");
    MethodInfo writeLineMI = typeof(Console).GetMethod("WriteLine",
                                new Type[] 
                                {typeof(string),
                                 typeof(object)});
                                                                   
    LocalBuilder tmp1 = adderIL.DeclareLocal(typeof(int));    
    LocalBuilder tmp2 = adderIL.DeclareLocal(typeof(OverflowException));

    Label failed = adderIL.DefineLabel();
    Label endOfMthd = adderIL.DefineLabel();

    // First, load argument 0 and the integer value of "100" onto the
    // stack. If arg0 > 100, branch to the label "failed", which is marked
    // as the address of the block that throws an exception.

    Label exBlock = adderIL.BeginExceptionBlock();
    adderIL.Emit(OpCodes.Ldarg_0);
    adderIL.Emit(OpCodes.Ldc_I4_S, 100);
    adderIL.Emit(OpCodes.Bgt_S, failed); 

    // Now, check to see if argument 1 was greater than 100. If it was,
    // branch to "failed." Otherwise, fall through and perform the addition,
    // branching unconditionally to the instruction at the label "endOfMthd".

    adderIL.Emit(OpCodes.Ldarg_1);
    adderIL.Emit(OpCodes.Ldc_I4_S, 100);
    adderIL.Emit(OpCodes.Bgt_S, failed);

    adderIL.Emit(OpCodes.Ldarg_0);
    adderIL.Emit(OpCodes.Ldarg_1);
    adderIL.Emit(OpCodes.Add_Ovf_Un);
    adderIL.Emit(OpCodes.Stloc_S, tmp1);
    adderIL.Emit(OpCodes.Br_S, endOfMthd);

    // If one of the arguments was greater than 100, we need to throw an
    // exception. We'll use "OverflowException" with a customized message.
    // First, we load our message onto the stack, and then create a new
    // exception object using the constructor overload that accepts a
    // string message.

    adderIL.MarkLabel(failed);
    adderIL.Emit(OpCodes.Ldstr, "Cannot accept values over 100 for add.");
    adderIL.Emit(OpCodes.Newobj, exCtorInfo);

    // We're going to need to refer to that exception object later, so let's
    // store it in a temporary variable. Since the store function pops the
    // the value/reference off the stack, and we'll need it to throw the
    // exception, we will subsequently load it back onto the stack as well.

    adderIL.Emit(OpCodes.Stloc_S, tmp2);
    adderIL.Emit(OpCodes.Ldloc_S, tmp2);

    // Throw the exception currently atop the stack.

    adderIL.ThrowException(typeof(OverflowException));
        
    // Start the catch block.

    adderIL.BeginCatchBlock(typeof(OverflowException));

    // First, we'll load a "wrapper" string, and then perform a 
    // late-bound call to the ToString() method of OverflowException,
    // passing it the exception object we stored in local variable tmp2.

    adderIL.Emit(OpCodes.Ldstr, "{0}");
    adderIL.Emit(OpCodes.Ldloc_S, tmp2);
    adderIL.EmitCall(OpCodes.Callvirt, exToStrMI, null);

    // Now, we should have the "wrapper" string atop the stack,
    // along with the string result of the ToString() call. All
    // conditions are met to call WriteLine(string, object).

    adderIL.EmitCall(OpCodes.Call, writeLineMI, null);

    // Since our function has to return an integer value, we'll load -1 onto
    // the stack to indicate an error, and store it in local variable tmp1.

    adderIL.Emit(OpCodes.Ldc_I4_M1);
    adderIL.Emit(OpCodes.Stloc_S, tmp1);

    // End the exception handling block.

    adderIL.EndExceptionBlock();    

    // The end of the method. If no exception was thrown, the correct value
    // will be saved in tmp1. If an exception was thrown, tmp1 will be equal
    // to -1. Either way, we'll load the value of tmp1 onto the stack and return.

    adderIL.MarkLabel(endOfMthd);
    adderIL.Emit(OpCodes.Ldloc_S, tmp1);
    adderIL.Emit(OpCodes.Ret);
    
    return myTypeBldr.CreateType();

   }

   public static void Main() {

    Type adderType = BuildAdderType();

    object addIns = Activator.CreateInstance(adderType); 

    object[] addParams = new object[2];

    Console.Write("Enter an integer value: ");
    addParams[0] = (object)Convert.ToInt32(Console.ReadLine());

    Console.Write("Enter another integer value: ");
    addParams[1] = (object)Convert.ToInt32(Console.ReadLine());

    Console.WriteLine("If either integer was > 100, an exception will be thrown.");
    Console.WriteLine("---");

    Console.WriteLine("{0} + {1} = {2}",
                addParams[0], addParams[1],
                adderType.InvokeMember("DoAdd",
                    BindingFlags.InvokeMethod,
                    null,
                    addIns,
                    addParams)); 
            
   }

}


[C++] 

#using <mscorlib.dll>

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

Type* BuildAdderType() {

   AppDomain*  myDomain = Thread::GetDomain();
   AssemblyName* myAsmName = new AssemblyName();
   myAsmName->Name = S"AdderExceptionAsm";
   AssemblyBuilder*  myAsmBldr = myDomain->DefineDynamicAssembly(myAsmName,
      AssemblyBuilderAccess::Run);

   ModuleBuilder*  myModBldr = myAsmBldr->DefineDynamicModule(S"AdderExceptionMod");

   TypeBuilder*  myTypeBldr = myModBldr->DefineType(S"Adder");

   Type* adderParams[] = {__typeof(int), __typeof(int)};

   // This method will add two numbers which are 100 or less. If either of the
   // passed integer vales are greater than 100, it will throw an exception.

   MethodBuilder*  adderBldr = myTypeBldr->DefineMethod(
      S"DoAdd",
      static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static),
      __typeof(int),
      adderParams);
   ILGenerator*  adderIL = adderBldr->GetILGenerator();

   // representing the offset IL instruction block to branch to.
   // These labels, when the MarkLabel(Label) method is invoked,
   // will specify the IL instruction to branch to.

   Type* temp0 [] = {__typeof(String)};
   ConstructorInfo*  exCtorInfo = __typeof(OverflowException)->GetConstructor(temp0);
   MethodInfo*  exToStrMI = __typeof(OverflowException)->GetMethod(S"ToString");

   Type* temp1 [] = {__typeof(String), __typeof(Object)};
   MethodInfo*  writeLineMI = __typeof(Console)->GetMethod(S"WriteLine",
      temp1);

   LocalBuilder*  tmp1 = adderIL->DeclareLocal(__typeof(int));
   LocalBuilder*  tmp2 = adderIL->DeclareLocal(__typeof(OverflowException));

   Label failed = adderIL->DefineLabel();
   Label endOfMthd = adderIL->DefineLabel();

   // First, load argument 0 and the integer value of S"100" onto the
   // stack. If arg0 > 100, branch to the label S"failed", which is marked
   // as the address of the block that throws an exception.

   Label exBlock = adderIL->BeginExceptionBlock();
   adderIL->Emit(OpCodes::Ldarg_0);
   adderIL->Emit(OpCodes::Ldc_I4_S, 100);
   adderIL->Emit(OpCodes::Bgt_S, failed);

   // Now, check to see if argument 1 was greater than 100. If it was,
   // branch to S"failed." Otherwise, fall through and perform the addition,
   // branching unconditionally to the instruction at the label S"endOfMthd".

   adderIL->Emit(OpCodes::Ldarg_1);
   adderIL->Emit(OpCodes::Ldc_I4_S, 100);
   adderIL->Emit(OpCodes::Bgt_S, failed);

   adderIL->Emit(OpCodes::Ldarg_0);
   adderIL->Emit(OpCodes::Ldarg_1);
   adderIL->Emit(OpCodes::Add_Ovf_Un);
   adderIL->Emit(OpCodes::Stloc_S, tmp1);
   adderIL->Emit(OpCodes::Br_S, endOfMthd);

   // If one of the arguments was greater than 100, we need to throw an
   // exception. We'll use "OverflowException" with a customized message.
   // First, we load our message onto the stack, and then create a new
   // exception Object using the constructor overload that accepts a
   // String* message.

   adderIL->MarkLabel(failed);
   adderIL->Emit(OpCodes::Ldstr, S"Cannot accept values over 100 for add.");
   adderIL->Emit(OpCodes::Newobj, exCtorInfo);

   // We're going to need to refer to that exception Object later, so let's
   // store it in a temporary variable. Since the store function pops the
   // the value/reference off the stack, and we'll need it to throw the
   // exception, we will subsequently load it back onto the stack as well.

   adderIL->Emit(OpCodes::Stloc_S, tmp2);
   adderIL->Emit(OpCodes::Ldloc_S, tmp2);

   // Throw the exception currently atop the stack.

   adderIL->ThrowException(__typeof(OverflowException));

   // Start the catch block.

   adderIL->BeginCatchBlock(__typeof(OverflowException));

   // First, we'll load a "wrapper" String, and then perform a
   // late-bound call to the ToString() method of OverflowException,
   // passing it the exception Object we stored in local variable tmp2.

   adderIL->Emit(OpCodes::Ldstr, S" {0}");
   adderIL->Emit(OpCodes::Ldloc_S, tmp2);
   adderIL->EmitCall(OpCodes::Callvirt, exToStrMI, 0);

   // Now, we should have the "wrapper" String atop the stack,
   // along with the String result of the ToString() call. All
   // conditions are met to call WriteLine(String*, Object*).

   adderIL->EmitCall(OpCodes::Call, writeLineMI, 0);

   // Since our function has to return an integer value, we'll load -1 onto
   // the stack to indicate an error, and store it in local variable tmp1.

   adderIL->Emit(OpCodes::Ldc_I4_M1);
   adderIL->Emit(OpCodes::Stloc_S, tmp1);

   // End the exception handling block.

   adderIL->EndExceptionBlock();

   // The end of the method. If no exception was thrown, the correct value
   // will be saved in tmp1. If an exception was thrown, tmp1 will be equal
   // to -1. Either way, we'll load the value of tmp1 onto the stack and return.

   adderIL->MarkLabel(endOfMthd);
   adderIL->Emit(OpCodes::Ldloc_S, tmp1);
   adderIL->Emit(OpCodes::Ret);

   return myTypeBldr->CreateType();

}

int main() {

   Type*  adderType = BuildAdderType();

   Object* addIns = Activator::CreateInstance(adderType);

   Object* addParams[] = new Object*[2];

   Console::Write(S"Enter an integer value: ");
   addParams[0] = __box(Convert::ToInt32(Console::ReadLine()));

   Console::Write(S"Enter another integer value: ");
   addParams[1] = __box(Convert::ToInt32(Console::ReadLine()));

   Console::WriteLine(S"If either integer was > 100, an exception will be thrown.");
   Console::WriteLine(S"---");

   Console::WriteLine(S" {0} + {1} = {2}",
      addParams[0], addParams[1],
      adderType->InvokeMember(S"DoAdd",
      BindingFlags::InvokeMethod,
      0,
      addIns,
      addParams));
}

[JScript] No example is available for JScript. To view a Visual Basic, C#, or C++ example, click the Language Filter button Language Filter in the upper-left corner of the page.

Requirements

Platforms: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 family

See Also

ILGenerator Class | ILGenerator Members | System.Reflection.Emit Namespace

Show: