[c#] try / catch / throw와 try / catch (e) / throw e의 차이점

차이점은 무엇입니까

try { }
catch
{ throw; }

try { }
catch(Exception e)
{ throw e;}

?

그리고 언제 둘 중 하나를 사용해야합니까?



답변

구조

try { ... }
catch () { ... } /* You can even omit the () here */

try { ... }
catch (Exception e) { ... }

둘 다 블록 내부에서 발생하는 모든 예외 를 포착한다는 점에서 비슷 합니다 try(이를 사용하여 예외를 기록하는 데 사용하지 않는 한 피해야합니다 ). 이제 이것들을보세요 :

try { ... }
catch ()
{
    /* ... */
    throw;
}

try { ... }
catch (Exception e)
{
    /* ... */
    throw;
}

try { ... }
catch (Exception e)
{
    /* ... */
    throw e;
}

첫 번째와 두 번째 try-catch 블록은 똑같습니다. 단순히 현재 예외를 다시 던지고 해당 예외가 “소스”와 스택 추적을 유지합니다.

세 번째 try-catch 블록은 다릅니다. 예외가 발생하면 소스와 스택 추적이 변경되어 throw e해당 try-catch 블록을 포함하는 메서드의 바로 그 줄에서이 메서드에서 예외가 throw 된 것처럼 보입니다 .

어느 것을 사용해야합니까? 각 경우에 따라 다릅니다.

데이터베이스에 유지 Person하는 .Save()메서드 가있는 클래스 가 있다고 가정 해 보겠습니다 . 애플리케이션이 Person.Save()어딘가 에서 메서드를 실행한다고 가정 해 보겠습니다 . DB가 Person 저장을 거부 .Save()하면 예외가 발생합니다. 당신이 사용해야 throw또는throw e 이 경우에 ? 음, 상황에 따라 다릅니다.

내가 선호하는 것은 다음과 같습니다.

try {
    /* ... */
    person.Save();
}
catch(DBException e) {
    throw new InvalidPersonException(
       "The person has an invalid state and could not be saved!",
       e);
}

이것은 DBException을 던지는 새로운 예외의 “내부 예외”로 넣어야합니다. 따라서이 InvalidPersonException을 검사 할 때 스택 추적에는 Save 메서드에 대한 정보가 포함되지만 (문제를 해결하는 데 충분할 수 있음) 필요한 경우 원래 예외에 계속 액세스 할 수 있습니다.

마지막으로, 예외를 예상 할 때 일반적인 예외가 아닌 특정 예외를 실제로 포착해야합니다 Exception. 즉, InvalidPersonException이 예상되는 경우 다음을 선호해야합니다.

try { ... }
catch (InvalidPersonException e) { ... }

try { ... }
catch (Exception e) { ... }

행운을 빕니다!


답변

첫 번째는 스택 추적을 보존하고 두 번째는 재설정합니다. 즉, 두 번째 접근 방식을 사용하면 예외의 스택 추적이 항상이 메서드에서 시작되며 예외의 원래 원인을 찾지 못하므로 예외 로그를 ​​읽는 사람에게 재앙이 될 수있는 원래 예외 추적을 잃게됩니다. .

두 번째 방법은 스택 추적에 추가 정보를 추가하려는 경우 유용 할 수 있지만 다음과 같이 사용됩니다.

try
{
    // do something
}
catch (Exception ex)
{
    throw new Exception("Additional information...", ex);
}

차이점을 논의 하는 블로그 게시물 이 있습니다.


답변

당신은 사용해야합니다

try { }
catch(Exception e)
{ throw }

다시 던지기 전에 예외로 무언가를하고 싶은 경우 (예 : 로깅). 외로운 던지기는 스택 추적을 유지합니다.


답변

매개 변수없는 catch와 a의 차이점 catch(Exception e)은 예외에 대한 참조를 얻는다는 것입니다. 프레임 워크 버전 2에서 관리되지 않는 예외는 관리되는 예외로 래핑되므로 매개 변수없는 예외는 더 이상 어떤 경우에도 유용하지 않습니다.

차이 throw;throw e;상기 제 하나의 예외를 다시 발생하는 데 사용되며, 두 번째는 새로 생성 된 예외를 발생하기 위해 사용된다는 점이다. 두 번째 예외를 사용하여 예외를 다시 발생 시키면 새 예외로 처리하고 원래 발생했던 모든 스택 정보를 대체합니다.

따라서 질문의 대안 중 하나를 사용하지 마십시오. 매개 변수없는 catch를 사용해서는 안되며 throw;예외를 다시 발생시키는 데 를 사용해야합니다 .

또한 대부분의 경우 모든 예외에 대해 기본 클래스보다 더 구체적인 예외 클래스를 사용해야합니다. 예상되는 예외 만 포착해야합니다.

try {
   ...
} catch (IOException e) {
   ...
   throw;
}

예외를 다시 던질 때 정보를 추가하려면 모든 정보를 보존하기 위해 원래 예외를 내부 예외로 사용하여 새 예외를 생성합니다.

try {
   ...
} catch (IOException e) {
   ...
   throw new ApplicationException("Some informative error message", e);
}


답변