ILGenerator.ThrowException-Methode
Gibt eine Anweisung zum Auslösen einer Ausnahme aus.
Namespace: System.Reflection.Emit
Assembly: mscorlib (in mscorlib.dll)
Syntax
'Declaration
Public Overridable Sub ThrowException ( _
excType As Type _
)
'Usage
Dim instance As ILGenerator
Dim excType As Type
instance.ThrowException(excType)
public virtual void ThrowException (
Type excType
)
public:
virtual void ThrowException (
Type^ excType
)
public void ThrowException (
Type excType
)
public function ThrowException (
excType : Type
)
Parameter
- excType
Die Klasse für den Typ der auszulösenden Ausnahme.
Ausnahmen
Ausnahmetyp | Bedingung |
---|---|
excType ist nicht die Exception-Klasse oder eine von Exception abgeleitete Klasse. – oder – Der Typ besitzt keinen Standardkonstruktor. |
|
excType ist NULL (Nothing in Visual Basic). |
Beispiel
Das folgende Codebeispiel veranschaulicht die kontextabhängige Verwendung von ThrowException zum Auslösen einer Ausnahme innerhalb der IL einer dynamischen Methode.
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
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));
}
}
using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type^ BuildAdderType()
{
AppDomain^ myDomain = Thread::GetDomain();
AssemblyName^ myAsmName = gcnew AssemblyName;
myAsmName->Name = "AdderExceptionAsm";
AssemblyBuilder^ myAsmBldr = myDomain->DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess::Run );
ModuleBuilder^ myModBldr = myAsmBldr->DefineDynamicModule( "AdderExceptionMod" );
TypeBuilder^ myTypeBldr = myModBldr->DefineType( "Adder" );
array<Type^>^adderParams = {int::typeid,int::typeid};
// 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", static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static), int::typeid, 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.
array<Type^>^temp0 = {String::typeid};
ConstructorInfo^ exCtorInfo = OverflowException::typeid->GetConstructor( temp0 );
MethodInfo^ exToStrMI = OverflowException::typeid->GetMethod( "ToString" );
array<Type^>^temp1 = {String::typeid,Object::typeid};
MethodInfo^ writeLineMI = Console::typeid->GetMethod( "WriteLine", temp1 );
LocalBuilder^ tmp1 = adderIL->DeclareLocal( int::typeid );
LocalBuilder^ tmp2 = adderIL->DeclareLocal( OverflowException::typeid );
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, "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( OverflowException::typeid );
// Start the catch block.
adderIL->BeginCatchBlock( OverflowException::typeid );
// 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, nullptr );
// 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, nullptr );
// 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 );
array<Object^>^addParams = gcnew array<Object^>(2);
Console::Write( "Enter an integer value: " );
addParams[ 0 ] = Convert::ToInt32( Console::ReadLine() );
Console::Write( "Enter another integer value: " );
addParams[ 1 ] = 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, nullptr, addIns, addParams ) );
}
Plattformen
Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.
Versionsinformationen
.NET Framework
Unterstützt in: 2.0, 1.1, 1.0
Siehe auch
Referenz
ILGenerator-Klasse
ILGenerator-Member
System.Reflection.Emit-Namespace