21 예외
21.1 일반
C#의 예외는 시스템 수준 및 애플리케이션 수준 오류 조건을 모두 처리하는 구조적이고 균일하며 형식이 안전한 방법을 제공합니다.
21.2 예외의 원인
예외는 두 가지 방법으로 throw될 수 있습니다.
throw
문(§13.10.6)은 즉시 무조건 예외를 throw합니다. 컨트롤은 바로 다음throw
문에 도달하지 않습니다.- C# 문 및 식을 처리하는 동안 발생하는 특정 예외 조건은 작업을 정상적으로 완료할 수 없는 특정 상황에서 예외가 throw됩니다. 이러한 방식으로 throw될 수 있는 다양한 예외 목록은 §21.5를 참조하세요.
예: 정수 나누기 작업(§12.10.3)은 분모가 0이면 throw
System.DivideByZeroException
합니다. 끝 예제
21.3 System.Exception 클래스
클래스는 System.Exception
모든 예외의 기본 형식입니다. 이 클래스에는 모든 예외가 공유하는 몇 가지 주목할 만한 속성이 있습니다.
Message
는 예외 이유에 대한 사람이 읽을 수 있는 설명을 포함하는 형식string
의 읽기 전용 속성입니다.InnerException
는 형식의 읽기 전용 속성입니다Exception
. 값이 아닌null
경우 현재 예외를 발생시킨 예외를 참조합니다. (즉, 현재 예외가 .를 처리하는InnerException
catch 블록에서 발생했습니다.) 그렇지 않으면 이 예외가 다른 예외로 인해 발생하지 않았음을 나타내는 값입니다null
. 이러한 방식으로 함께 연결된 예외 개체의 수는 임의일 수 있습니다.
이러한 속성의 값은 인스턴스 생성자에 대한 System.Exception
호출에서 지정할 수 있습니다.
21.4 예외 처리 방법
예외는 문(§13.11)으로 처리 try
됩니다.
예외가 throw되면(§21.2) 시스템은 예외의 런타임 형식에 따라 결정되는 예외를 처리할 수 있는 가장 가까운 catch 절을 검색합니다. 첫째, 현재 메서드는 어휘적으로 바깥쪽 try
문을 검색하고 문의 연결된 catch
절을 순서대로 고려합니다 try
. 실패하면 현재 메서드를 호출한 메서드가 현재 메서드에 대한 호출 지점을 묶는 어휘적으로 바깥쪽 try
문을 검색합니다. 이 검색은 throw되는 예외의 런타임 형식과 동일한 클래스 또는 기본 클래스의 예외 클래스 이름을 지정하여 현재 예외를 처리할 수 있는 절이 발견될 때까지 catch
계속됩니다. catch
예외 클래스의 이름을 지정하지 않는 절은 예외를 처리할 수 있습니다.
일치하는 catch
절이 발견되면 시스템은 절의 catch
첫 번째 문으로 제어를 전송할 준비를 합니다. 절 실행이 catch
시작되기 전에 시스템은 먼저 문과 try
연결된 모든 finally
절이 예외를 catch한 절보다 중첩된 모든 절을 순서대로 실행합니다.
일치하는 catch
절이 없으면 다음을 수행합니다.
- 일치하는
catch
절에 대한 검색이 정적 생성자(§15.12) 또는 정적 필드 이니셜라이저System.TypeInitializationException
에 도달하면 정적 생성자의 호출을 트리거한 지점에서 throw됩니다. 내부 예외에는System.TypeInitializationException
원래 throw된 예외가 포함됩니다. - 그렇지 않으면 종료자 실행 중에 예외가 발생하고 해당 예외가 catch되지 않으면 동작이 지정되지 않습니다.
- 그렇지 않으면 일치하는
catch
절에 대한 검색이 처음에 스레드를 시작한 코드에 도달하면 스레드 실행이 종료됩니다. 이러한 종료의 영향은 구현에서 정의됩니다.
21.5 일반적인 예외 클래스
다음 예외는 특정 C# 작업에서 throw됩니다.
예외 유형 | 설명 |
---|---|
System.ArithmeticException |
System.DivideByZeroException , System.OverflowException 등의 산술 연산 중에 발생하는 예외에 대한 기본 클래스입니다. |
System.ArrayTypeMismatchException |
저장된 요소의 형식이 배열의 형식과 호환되지 않으므로 저장소가 배열에 실패할 때 throw됩니다. |
System.DivideByZeroException |
정수 값을 0으로 나누려는 시도가 발생하면 throw됩니다. |
System.IndexOutOfRangeException |
0보다 작거나 배열 범위 밖에 있는 인덱스를 통해 배열을 인덱싱하려고 할 때 throw됩니다. |
System.InvalidCastException |
런타임에 기본 형식 또는 인터페이스에서 파생 형식으로의 명시적 변환이 실패할 때 throw됩니다. |
System.NullReferenceException |
참조된 개체가 null 필요한 방식으로 참조를 사용할 때 throw됩니다. |
System.OutOfMemoryException |
메모리 할당 시도(통해 new )가 실패할 때 throw됩니다. |
System.OverflowException |
checked 컨텍스트의 산술 연산이 오버플로될 경우 throw됩니다. |
System.StackOverflowException |
보류 중인 호출이 너무 많아 실행 스택이 소진되면 throw됩니다. 일반적으로 매우 깊거나 바인딩되지 않은 재귀를 나타냅니다. |
System.TypeInitializationException |
정적 생성자 또는 정적 필드 이니셜라이저가 예외를 throw하고 catch할 절이 없을 catch 때 throw됩니다. |
ECMA C# draft specification