예외가 포착 된 다음 다시 throw되면 예외가 원래 위치가 아닌 재실행 시점에서 발생한 것처럼 스택 추적이 나타납니다. 바라건대, 당신의 코드에서 그렇게 많은 것들이 진행되지는 않을 것입니다. 그렇지 않으면 스택 추적만으로 예외 위치를 구별 할 수 있습니다.
또 다른 문제점은 스택 추적이 동일하여 실제적으로 동일 할 때 두 가지 예외가 아닌 것처럼 보일지 여부입니다. 스택 트레이스는 내 경험상 동일하기 때문에 문제가 될 수 없습니다. (예외 오브젝트에 있으며, toString() 결과는 일반적으로 동일하지 않습니다.)
이
상황이 Exception.StackTrace
가 손상 될 것입니다 정확히 무엇에 대한 몇 가지 논란이 있었다 업데이트되었습니다. 기본 규칙은 언제든지
throw *expression*;
이 *expression*
식별이 StackTrace
속성 집합있을 것이라는 점을 다음 Exception
객체를 실행한다는 것입니다. *expression*
이 생략 된 경우
throw;
그러면 StackTrace가 적용되지 않습니다.
이 두 형식의 용어를 찾을 수 없으므로 각 형식을 "명시 적"및 "암시 적"이라고 각각 부릅니다. *expression*
이 해결하는 예외 개체가 new
인지 또는 이미 존재하는 개체인지 여부는 중요하지 않습니다.여기
이 동작을 설명하기위한 프로그램이다
using System;
namespace FunWithExceptions
{
class Program
{
static void Main(string[] args)
{
try { Replace(); }
catch (InvalidOperationException ex) { DisplayResult("Replace resulted in", ex); }
try { RethrowExplicit(); }
catch (InvalidOperationException ex) { DisplayResult("RethrowExplicit resulted in", ex); }
try { RethrowImplicit(); }
catch (InvalidOperationException ex) { DisplayResult("RethrowImplicit resulted in", ex); }
InvalidOperationException myException = new InvalidOperationException();
DisplayResult("myException starts with", myException);
try { throw myException; }
catch (InvalidOperationException) { }
DisplayResult("myException changes to", myException);
Console.ReadLine();
}
static void ThrowAnException()
{ throw new InvalidOperationException("You messed up!"); }
static void Replace()
{
try { ThrowAnException(); }
catch (InvalidOperationException ex)
{
DisplayResult("Replace caught", ex);
throw new InvalidOperationException("Another mistake.");
}
}
static void RethrowExplicit()
{
try { ThrowAnException(); }
catch (InvalidOperationException ex)
{
DisplayResult("RethrowExplicit caught", ex);
throw ex;
}
}
static void RethrowImplicit()
{
try { ThrowAnException(); }
catch (InvalidOperationException ex)
{
DisplayResult("RethrowImplicit caught", ex);
throw;
}
}
static void DisplayResult(string context, Exception ex)
{
Console.WriteLine("{0} exception thrown at {1}", context, FirstMethodName(ex.StackTrace));
}
private const string methodNamePrefix = " at FunWithExceptions.Program.";
private static object FirstMethodName(string stackTrace)
{
stackTrace = stackTrace ?? string.Empty;
if (stackTrace.StartsWith(methodNamePrefix))
stackTrace = stackTrace.Substring(methodNamePrefix.Length);
int methodNameEndIndex = stackTrace.IndexOf(')');
if (methodNameEndIndex != -1)
stackTrace = stackTrace.Substring(0, methodNameEndIndex + 1);
if (stackTrace.Length > 0)
return stackTrace;
else
return "--empty--";
}
}
}
다음 출력 결과를이 프로그램 :
하는 ThrowAnException (던져 잡힌 예외)
바꾸기 예외 결과 바꾸기 Replace()에서 throw 됨
RethrowExplicit catch throw 예외 : ThrowAnException()
RethrowExplicit는 RethrowExplicit 던져 예외()
RethrowImplicit가 ThrowAnException 던져 예외() 결과 ThrowAnException()에서 발생 RethrowImplicit 잡힌 예외
myException 슬로우 예외 시작 초래 at --empty--
메인에서 예외가 변경됨 (String [] args)
6 번째 줄이 흥미 롭습니다.
저기, 나는이 시점에서 완전히 죽음에 이릅니다. :-)
왜 스택 트레이스를 필요합니까? 이름만으로 그걸 알아낼 수 없습니까? 아니면 내가 여기서 당신의 요점을 놓치고 있습니까? – Adi
은 예제를 추가하여 희망적으로 자신을 명확하게 만듭니다. –