.NET에서는 캐치가 단지 재창조되는 시도/캐치에 이점이 있습니까?

StackOverflow https://stackoverflow.com/questions/1207172

  •  05-07-2019
  •  | 
  •  

문제

가능한 복제 :
C#에서 예외를 잡아야하는 이유는 무엇입니까?

나는 때때로 다음과 같은 것처럼 보이는 c# 코드를 발견합니다.

        try
        {
            // Some stuff
        }
        catch (Exception e)
        {
            throw e;
        }

예외 메시지를 기록한 다음 재검토 할 수 있다는 것을 이해합니다. 나는 예외 만 재창조하는 캐치에 대해 이야기하고 있습니다. 나는 이것에 대한 요점을 보지 못한다. 세 가지 질문이 있습니다.

1) 이것에 대한 이점이 있습니까?

2)이 느린 코드가 전혀

3) 캐치 블록이 다음과 같다면 차이가 있습니까?

        catch (Exception)
        {
            throw;
        }
도움이 되었습니까?

해결책

이것은 재창조된다 정확한 동일한 예외 :

    catch (Exception)
    {
        throw;
    }

반면, 이것은 원래 스택 추적없이 예외를 재창조합니다.

    catch (Exception e)
    {
        throw e;
    }

종종 좋은 이유가 있습니다 throw; 예외를 기록하거나 예외를 재고하기 전에 다른 일을 할 수 있으므로. 나는 좋은 이유를 알지 못합니다 throw e; 귀중한 스택 추적 정보를 닦을 수 있습니다.

다른 팁

당신이 캐치에서 다른 일을하지 않는다면 ... 그러나 이것은 종종 로깅 또는 다른 종류의 예외를 재생하기 전에 캐치에서 다른 일을하는 데 사용됩니다.

나는 그 기술을 사용하여 디버깅 할 때 던지기에 중단 점을 넣을 수 있습니다. 때때로 나는 끝난 후에 그것을 제거합니다 ...

주요 차이점은 예외의 스택 트레이스가 첫 번째 예제에서 Try-Catch의 위치에서 시작되었음을 보여주기 위해 변경 될 것입니다.

두 번째 예제는 스택 추적을 유지합니다.

이점이 있습니까?

일반적으로 말하자면. 이 패턴은 스택 추적을 새로운 던지기의 지점으로 재설정하는 것입니다. 이것은 개발자가 문제의 원인을 추적하기가 더 어려워 질 것입니다.

코드가 전혀 느려집니다

조금도? 혹시. 측정 가능한 차이로 인해 느리게 하시겠습니까? 아니.

캐치 블록이 다음과 같이 차이가 있습니까?

예, 그 캐치는 본질적으로 완전히 중복됩니다. 원래 스택 추적을 유지하고 응용 프로그램에 영향을 미치지 않는 예외를 재고합니다.

1- 나는 전혀 장점이 없다. 예외를 처리하지 않으면 시도/캐치를 떠나십시오. 이 예제의 또 다른 문제는 실제 예외가 아니라 새로운 예외를 던지는 것입니다.

2- 예 - 그러나 이것이 반복 된 코드의 큰 고리에 앉아 있지 않으면 차이를 알지 못할 것입니다.

3- 예. 첫 번째 예에서는 콜 스택을 엉망으로 만들고 있습니다. 이 예제는 스택을 새로 던지는 대신 예외를 거품으로하여 스택을 그대로 유지합니다.

당신이 정말로 다른 일을하지 않는다면, 내가 찾은 이점은 하나뿐입니다. throw 선. 예외 유형이 던져 질 때마다 깨지는 대신 매우 구체적입니다.

그래도 디버깅하는 동안 만 그렇게하고 코드를 되돌립니다.

차이점을 보여주기 위해 빠른 테스트를 작성했습니다. 테스트 코드는 다음과 같습니다.

try
{
    var broken = int.Parse("null");
}
catch (Exception ex1)
{
    System.Diagnostics.Trace.WriteLine(ex1.ToString());
}

try
{
    try
    {
        var broken = int.Parse("null");
    }
    catch (Exception)
    {
        throw;
    }
}
catch (Exception ex2)
{
    System.Diagnostics.Trace.WriteLine(ex2.ToString());
}

try
{
    try
    {
        var broken = int.Parse("null");
    }
    catch (Exception ex3)
    {
        throw ex3;
    }
}
catch (Exception ex4)
{
    System.Diagnostics.Trace.WriteLine(ex4.ToString());
}

이것을 실행하면 다음과 같은 출력을 얻습니다.

A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int32.Parse(String s)
   at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 18
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
A first chance exception of type 'System.FormatException' occurred in QuickTests.exe
System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Int32.Parse(String s)
   at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 33
A first chance exception of type 'System.FormatException' occurred in mscorlib.dll
A first chance exception of type 'System.FormatException' occurred in QuickTests.exe
System.FormatException: Input string was not in a correct format.
   at QuickTests.Program.Main(String[] args) in C:\Projects\Test\QuickTests\Program.cs:line 49

처음 두 가지 예외는 같은 방식으로 작동한다는 것을 알 수 있습니다. 그래서 "던지기;" 스택을 올라가는 예외까지는 아무것도 바꾸지 않습니다. 그러나 "ex3를 던지기"; 보고 된 예외가 다르기 때문에 예외를 위해 스택 추적을 변경합니다.

로깅에 종종 좋습니다. 또한 재단에서 인수를 남기면 e의 스택 추적을 변경하지 않습니다.

때로는 특정 유형을 통해 허용하기를 원합니다. 예를 들어, 여기에는 fooxception 이외의 모든 것에 대한 특별 처리가 있습니다.

try
{
    // ...
}
catch (FooException)
{
    throw;
}
catch (Exception ex)
{
    // handle differently, like wrap with a FooException
    throw new FooException("I pitty the Foo.", ex);
}

확신하는.

대부분은 예외를 던지기 전에 예외를 기록하고 메소드에서 변수 값을 기록하려고합니다.

그러나 그것을 던지기 위해 그것을 잡는 것만으로도 당신을 많이 얻지 못합니다.

그런 식으로, 아니요. 그러나이 작업을 수행 할 수 있습니다.

catch (Exception ex)
{
     LogException(ex);
     throw;
}

여기서 logexception ()은 예외를 기록하거나 경고 또는 무언가를 이메일로 보내는 사용자 정의 클래스입니다.

요점은 한 가지 유형의 예외 만 던져 지도록하는 것입니다. 그것은 꽤 나쁜 반 패턴 IMHO입니다

예를 들어

try
{
    throw XYZ();
}
catch(Exception e)
{
    throw e;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top