特にオプションを指定せずにType.InvokeMemberメソッドやMethodInfo.Invokeメソッドなどによってメンバを呼び出し、呼び出した先で例外が発生した場合、その例外はTargetInvocationExceptionにラップされた上でスローされます。
BindingFlags.DoNotWrapExceptionsを指定することにより、発生した例外をTargetInvocationExceptionにラップしないようにすることができます。 これにより、発生した例外そのものを捕捉できるようになります。 DoNotWrapExceptionsは.NET Standard 2.1/.NET Core 2.1以降で使用することができます。
BindingFlags.DoNotWrapExceptionsを指定して例外をそのままでスローさせる .NET Standard 2.1/.NET Core 2.1
Imports System
Imports System.Reflection
Class C
Public Sub M()
Throw New NotImplementedException()
End Sub
End Class
Class Sample
Shared Sub Main()
Dim t As Type = GetType(C)
Dim inst As Object = Activator.CreateInstance(t)
Dim m As MethodInfo = t.GetMethod("M")
Try
' MethodInfo.Invokeを使ってメソッドを呼び出す
' BindingFlags.DoNotWrapExceptionsを指定することにより、
' 発生した例外をTargetInvocationExceptionにラップさせず、そのままでスローさせる
m.Invoke(inst, BindingFlags.DoNotWrapExceptions, parameters := Nothing, binder := Nothing, culture := Nothing)
Catch ex As NotImplementedException
Console.WriteLine(ex) ' メソッドがスローする例外がそのまま捕捉される
Catch ex As TargetInvocationException
Console.WriteLine(ex) ' TargetInvocationExceptionはスローされないので、ここでは捕捉されない
End Try
End Sub
End Class
実行結果
System.NotImplementedException: The method or operation is not implemented. at C.M() at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) at Sample.Main()