code

이러한 예외를 던지지 않는 이유는 무엇입니까?

codestyles 2020. 8. 18. 07:43
반응형

이러한 예외를 던지지 않는 이유는 무엇입니까?


나는 우연히 이 MSDN 페이지 상태가 :

자체 소스 코드에서 의도적으로 Exception , SystemException , NullReferenceException 또는 IndexOutOfRangeException을 발생 시키지 마십시오 .

불행히도 그 이유를 설명 할 필요가 없습니다. 나는 그 이유를 추측 할 수 있지만 주제에 대해 더 권위있는 누군가가 그들의 통찰력을 제공 할 수 있기를 바랍니다.

처음 두 가지는 분명한 의미가 있지만, 후자의 두 가지는 당신이 고용하고 싶은 것 같습니다 (사실 저는 가지고 있습니다).

또한 이것들이 피해야 할 유일한 예외입니까? 다른 사람이 있다면 무엇이며 왜 피해야합니까?


Exception모든 예외에 대한 기본 유형이므로 매우 구체적이지 않습니다. 유용한 정보가 포함되어 있지 않기 때문에이 예외를 throw해서는 안됩니다. 예외를 포착하는 코드를 호출하는 것은 완전히 원하지 않는 다른 시스템 예외에서 의도적으로 throw 된 예외 (논리에서)를 명확하게 할 수 없으며 실제 오류를 지적 할 수 없습니다.

같은 이유가 SystemException. 파생 된 유형 목록을 보면 매우 다른 의미를 가진 수많은 다른 예외를 볼 수 있습니다.

NullReferenceException그리고 IndexOutOfRangeException다른 종류의 수 있습니다. 이제 이들은 매우 구체적인 예외는, 그래서 그들이 던지는 괜찮을. 그러나 일반적으로 논리에 실제 실수가 있음을 의미하므로 여전히 던지고 싶지 않을 것입니다. 예를 들어 null 참조 예외는 인 개체의 멤버에 액세스하려고 함을 의미합니다 null. 그것이 당신의 코드에서 가능성이 있다면, 당신은 항상 명시 적으로 null더 유용한 예외를 확인 하고 대신 던져야합니다 (예 ArgumentNullException:). 마찬가지로 IndexOutOfRangeExceptions는 목록이 아닌 배열에서 잘못된 인덱스에 액세스 할 때 발생합니다. 항상 처음에는 그렇게하지 않도록하고 배열의 경계를 먼저 확인해야합니다.

몇 가지 다른 예를 들어 두 같은 예외가 있습니다 InvalidCastException또는 DivideByZeroException코드에서 특정 오류에 대한 던져 일반적으로 당신이 뭔가 잘못을하고 또는 당신이 먼저 몇 가지 잘못된 값을 검사하지 않는 것을 의미하고 있습니다. 코드에서 의도적으로 던짐으로써 호출 코드가 코드의 일부 결함으로 인해 던진 것인지 또는 구현에서 무언가를 위해 재사용하기로 결정했기 때문에 발생했는지 확인하기가 더 어려워집니다.

물론 이러한 규칙에는 몇 가지 예외 (하)가 있습니다. 기존의 것과 정확히 일치하는 예외를 유발할 수있는 무언가를 빌드하는 경우, 특히 내장 된 동작과 일치시키려는 경우 자유롭게 사용하십시오. 그런 다음 매우 구체적인 예외 유형을 선택했는지 확인하십시오.

그러나 일반적으로 필요를 충족하는 (특정) 예외를 찾지 않는 한 항상 특정 예상 예외에 대한 고유 한 예외 유형을 만드는 것을 고려해야합니다. 특히 라이브러리 코드를 작성할 때 예외 소스를 분리하는 데 매우 유용 할 수 있습니다.


마지막 2의 의도는 예상되는 의미를 가진 내장 된 예외와의 혼동을 방지하는 것입니다. 그러나, 나는 그 의견 해요 당신이 예외의 정확한 의도를 보존하는 경우 : 그것은 올바른 하나입니다 throw. 예를 들어 사용자 지정 컬렉션을 작성하는 경우 IndexOutOfRangeExceptionIMO보다 명확하고 구체적인 IMO 를 사용하는 것이 전적으로 합리적으로 보입니다 ArgumentOutOfRangeException. 반면 List<T>후자를 선택할 수있다 적어도 (배열을 포함하지 않음) BCL 41 곳 (반사판의 제공) 맞춤이 던져 IndexOutOfRangeException특별 공제를받을 자격 "낮은 수준"충분히있는 아무 것도 없음은 -. 그래서 네, 그 지침이 어리 석다고 주장 할 수 있다고 생각합니다. 마찬가지로,NullReferenceException 확장 메서드에서 유용합니다-의미 체계를 유지하려는 경우 :

obj.SomeMethod(); // this is actually an extension method

A는 발생 NullReferenceException하는 경우 obj입니다 null.


지적했듯이 예외를 던질 때 피할 일 항목 아래의 예외 만들기 및 던지기 (C # 프로그래밍 가이드) 문서 에서 Microsoft는 실제로 사용자 고유의 소스 코드에서 의도적으로 throw해서는 안되는 예외 유형을 나열 합니다.System.IndexOutOfRangeException

그러나 반대로 기사 throw (C # Reference) 에서 Microsoft는 자체 지침을 위반하는 것으로 보입니다. 다음은 Microsoft가 예제에 포함시킨 방법입니다.

static int GetNumber(int index)
{
    int[] nums = { 300, 600, 900 };
    if (index > nums.Length)
    {
        throw new IndexOutOfRangeException();
    }
    return nums[index];
}

따라서 Microsoft 자체는 IndexOutOfRangeException문서에서 의 던짐을 보여 주므로 일관성이 없습니다 throw.

이것은 적어도의 경우 에는 프로그래머 IndexOutOfRangeException가 예외 유형 던지고 수용 가능한 관행으로 간주 될 수있는 경우가있을 수 있다고 믿게합니다 .


내가 질문을 읽을 때, 나는 하나의 예외 유형을 던져 원하는 것이 무엇 조건에서 자신을 요청 NullReferenceException, InvalidCastException또는 ArgumentOutOfRangeException.

제 생각에는 이러한 예외 유형 중 하나가 발생할 때 컴파일러가 저에게 말하고 있다는 의미에서 (개발자) 경고가 걱정됩니다. 따라서 개발자 (개발자)가 이러한 예외 유형을 던지도록 허용하는 것은 (컴파일러) 책임을 판매하는 것과 같습니다. 예를 들어, 이것은 컴파일러가 이제 개발자가 객체가 null. 그러나 그러한 결정을 내리는 것은 실제로 컴파일러의 일이어야합니다.

추신 : 2003 년부터는 원하는대로 예외를 처리 할 수 ​​있도록 자체적으로 예외를 개발해 왔습니다. 그렇게하는 것이 가장 좋은 방법이라고 생각합니다.

참고 URL : https://stackoverflow.com/questions/22453650/why-are-we-not-to-throw-these-exceptions

반응형