他の答えは完全に正しいですが、この答えはいくつかの余分な詳細を提供すると思います。
この例を考えてみましょう:
using System;
static class Program {
static void Main() {
try {
ThrowTest();
} catch (Exception e) {
Console.WriteLine("Your stack trace:");
Console.WriteLine(e.StackTrace);
Console.WriteLine();
if (e.InnerException == null) {
Console.WriteLine("No inner exception.");
} else {
Console.WriteLine("Stack trace of your inner exception:");
Console.WriteLine(e.InnerException.StackTrace);
}
}
}
static void ThrowTest() {
decimal a = 1m;
decimal b = 0m;
try {
Mult(a, b); // line 34
Div(a, b); // line 35
Mult(b, a); // line 36
Div(b, a); // line 37
} catch (ArithmeticException arithExc) {
Console.WriteLine("Handling a {0}.", arithExc.GetType().Name);
// uncomment EITHER
//throw arithExc;
// OR
//throw;
// OR
//throw new Exception("We handled and wrapped your exception", arithExc);
}
}
static void Mult(decimal x, decimal y) {
decimal.Multiply(x, y);
}
static void Div(decimal x, decimal y) {
decimal.Divide(x, y);
}
}
このthrow arithExc;
行のコメントを外すと、出力は次のようになります。
Handling a DivideByZeroException.
Your stack trace:
at Program.ThrowTest() in c:\somepath\Program.cs:line 44
at Program.Main() in c:\somepath\Program.cs:line 9
No inner exception.
確かに、その例外が発生した場所に関する情報を失っています。代わりにthrow;
行を使用すると、次のようになります。
Handling a DivideByZeroException.
Your stack trace:
at System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
at System.Decimal.Divide(Decimal d1, Decimal d2)
at Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs:line 58
at Program.ThrowTest() in c:\somepath\Program.cs:line 46
at Program.Main() in c:\somepath\Program.cs:line 9
No inner exception.
これは、Program.Div
問題の原因となった方法であることがわかります。しかし、この問題がtry
ブロックの35行目または37行目にあるかどうかを確認することは依然として困難です。
3番目の選択肢を使用する場合、外側の例外でラップしても、情報は失われません。
Handling a DivideByZeroException.
Your stack trace:
at Program.ThrowTest() in c:\somepath\Program.cs:line 48
at Program.Main() in c:\somepath\Program.cs:line 9
Stack trace of your inner exception:
at System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
at System.Decimal.Divide(Decimal d1, Decimal d2)
at Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs:line 58
at Program.ThrowTest() in c:\somepath\Program.cs:line 35
特に、問題につながるのは35行目です。ただし、これを行うにはを検索する必要がInnerException
あり、単純なケースで内部例外を使用することは多少間接的に感じられます。
で、このブログの記事彼らは(反射による)を呼び出すことで、行番号(tryブロックのラインを)維持internal
intance法InternalPreserveStackTrace()
上のException
オブジェクト。しかし、そのようなリフレクションを使用するのは良いことではありません(.NET Frameworkはinternal
いつの日か警告なしにメンバーを変更する可能性があります)。