動的にメソッド呼び出すと例外が InnerException になる
◯ 普通に呼び出し
◯ Action 型にメソッドを代入して Invoke で呼び出し
◯ Action 型にメソッドを代入して DynamicInvoke で呼び出し
◯ リフレクションで呼び出し

それぞれの方法でメソッドを呼び出す
呼び出されるメソッドは例外を発生させる

public void Button_Click(object sender, RoutedEventArgs e)
{
Console.WriteLine("standard call+++++++++");
try
{
this.method1();
}
catch (Exception ex)
{
Console.WriteLine($"catch at Button_Click: {ex.Message}");
Console.WriteLine($"-- inner exception: {ex.InnerException?.Message}");
}

Console.WriteLine("\ndelegate call+++++++");
try
{
Action fn = this.method1;
fn.Invoke();
}
catch (Exception ex)
{
Console.WriteLine($"catch at Button_Click: {ex.Message}");
Console.WriteLine($"-- inner exception: {ex.InnerException?.Message}");
}

Console.WriteLine("\ndelegate dynamic call+++++++");
try
{
Action fn = this.method1;
fn.DynamicInvoke(null);
}
catch (Exception ex)
{
Console.WriteLine($"catch at Button_Click: {ex.Message}");
Console.WriteLine($"-- inner exception: {ex.InnerException?.Message}");
}

Console.WriteLine("\nreflection call+++++++");
try
{
this.GetType().GetMethod("method1").Invoke(this, null);
}
catch (Exception ex)
{
Console.WriteLine($"catch at Button_Click: {ex.Message}");
Console.WriteLine($"-- inner exception: {ex.InnerException?.Message}");
}
}

public void method1()
{
try
{
method2();
}
catch (Exception ex)
{
Console.WriteLine($"catch method1: {ex.Message}");
Console.WriteLine($"-- inner exception: {ex.InnerException?.Message}");
throw;
}
}

public void method2()
{
throw new Exception("えらー");
}

結果は下 2 つの動的な呼び出しだと catch した例外は TargetInvocationException になってる
その InnerException に呼び出したメソッドで実際に発生した例外が入ってる

standard call+++++++++
catch method1: えらー
-- inner exception:
catch at Button_Click: えらー
-- inner exception:

delegate call+++++++
catch method1: えらー
-- inner exception:
catch at Button_Click: えらー
-- inner exception:

delegate dynamic call+++++++
catch method1: えらー
-- inner exception:
catch at Button_Click: 呼び出しのターゲットが例外をスローしました。
-- inner exception: えらー

reflection call+++++++
catch method1: えらー
-- inner exception:
catch at Button_Click: 呼び出しのターゲットが例外をスローしました。
-- inner exception: えらー
C# の例外の投げ直しは throw だけ
C# で例外を catch したときにログするなどして もっかい throw するときは throw だけで例外を指定するとダメ

private void Button_Click(object sender, RoutedEventArgs e)
{
try
{
this.method_1(); // Line.33
}
catch(Exception ex)
{
Console.WriteLine("method_1********");
Console.WriteLine("message:");
Console.WriteLine(ex.Message);
Console.WriteLine("stacktrace:");
Console.WriteLine(ex.StackTrace);
}

Console.WriteLine("");

try
{
this.method_2(); // Line.48
}
catch (Exception ex)
{
Console.WriteLine("method_2********");
Console.WriteLine("message:");
Console.WriteLine(ex.Message);
Console.WriteLine("stacktrace:");
Console.WriteLine(ex.StackTrace);
}
}

private void method_1()
{
try
{
exceptionMethod();
}
catch (Exception ex)
{
throw ex; // Line.68
}
}

private void method_2()
{
try
{
exceptionMethod();
}
catch (Exception)
{
throw; // Line.80
}
}

public void exceptionMethod()
{
throw new Exception("えらー"); // Line.86
}

throw ex で例外指定と throw だけのときでスタックトレースが変わる

method_1********
message:
えらー
stacktrace:
場所 samproj.Window4.method_1() 場所 C:\Users\user\Documents\Visual Studio 2015\Projects\samproj\proj02\Window4.xaml.cs:行 68
場所 samproj.Window4.Button_Click(Object sender, RoutedEventArgs e) 場所 C:\Users\user\Documents\Visual Studio 2015\Projects\samproj\proj02\Window4.xaml.cs:行 33

method_2********
message:
えらー
stacktrace:
場所 samproj.Window4.exceptionMethod() 場所 C:\Users\user\Documents\Visual Studio 2015\Projects\samproj\proj02\Window4.xaml.cs:行 86
場所 samproj.Window4.method_2() 場所 C:\Users\user\Documents\Visual Studio 2015\Projects\samproj\proj02\Window4.xaml.cs:行 80
場所 samproj.Window4.Button_Click(Object sender, RoutedEventArgs e) 場所 C:\Users\user\Documents\Visual Studio 2015\Projects\samproj\proj02\Window4.xaml.cs:行 48

throw だけだと元のを保持してくれる
throw ex にすると再度 throw したところになるので正確な場所がわからなくなる