Middle · Trace · Reflection invocation and exception boundaries

Predict the wrapper and inner exception names, then compare the directly invoked delegate.

Think through your answer before opening the explanation.

Runtime & concurrency

using System;
using System.Linq;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Reflection;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;

var method = typeof(Rules).GetMethod(nameof(Rules.Positive))!;
try { method.Invoke(null, new object?[] { 0 }); }
catch (TargetInvocationException error)
{
    Console.WriteLine($"outer:{error.GetType().Name}");
    Console.WriteLine($"inner:{error.InnerException!.GetType().Name}");
}
Func<int, int> direct = Rules.Positive;
try { direct(0); } catch (ArgumentOutOfRangeException error) { Console.WriteLine($"delegate:{error.GetType().Name}"); }
static class Rules { public static int Positive(int value) => value > 0 ? value : throw new ArgumentOutOfRangeException(nameof(value)); }
Reveal answer and reasoning

The output is outer:TargetInvocationException, inner:ArgumentOutOfRangeException, and delegate:ArgumentOutOfRangeException. Rules.Positive rejects zero in both cases. The reflected call uses a known valid member and argument shape, so execution reaches the target body; its range exception is the cause wrapped by that invocation API. The directly typed delegate reaches the same body without adding that reflection wrapper.

The program catches specific categories and prints only type names, so no regional exception-message text enters the expectation. It does not demonstrate a missing method, incompatible argument, or faulted asynchronous return. A common wrong trace prints the domain exception as the first outer line, or adds another wrapper to the directly called delegate. Follow the actual call mechanism rather than assuming a delegate discovered or described by metadata must behave like a fresh reflective invocation on every call.

What a strong answer covers

  • The reflection outer type is TargetInvocationException.
  • Its inner type is the target range exception.
  • Direct delegate invocation exposes the target exception.

Common pitfall

Ignoring the distinction between reflective invocation and a directly typed delegate call.

Follow-up questions

  1. What changes for valid input one?
  2. What changes if argument binding fails before target execution?

Self-review

Choose what to revisit. These marks are your own assessment and are separate from lesson completion.

Primary references

Open lesson and code ↗

← All interview questions