예외처리란 프로그램 실행 중 발생할 수 있는 예외 상황을 처리하는 코드이다.
기본적으로 C#에서 예외 처리는 **try-catch**
문을 사용하여 수행된다.
기본적인 사용 방법은 다음과 같다. Try{ 검사내용 } catch { 에러 메시지 출력 }
입력을 받았을 때, 오류라면 try 내의 함수를 생략한다.
위 코드에서 사용자가 잘못된 값을 입력했을 경우, isFinished가 스킵되기 때문에
올바른 값을 입력할 때까지, 반복문이 계속된다.
**FormatException**
을 이용하여,
input값을 확인하여 잘못된 값(맞지않은 포맷값)을 입력하면 메시지를 출력하게 만들 수 있다.
오버플로우를 체크하는 예외처리는 **OverFlowException**
키워드이다.
모든 예외는 Exception
에서 필터링된다.
즉, Exception이 다른 모든 예외를 포함하는 부모와 마찬가지이다.
그렇기에, Exception으로 예외처리를 한다면, 아래에 새로운 catch문을 작성할 수가 없다.
따라서 Exception만을 이용해서 모든 예외처리를 할 수 있지만, 코드의 가독성을 위해서 세부 Exception을 한다.
즉, OverFlowException을 키워드로 사용하여 에러를 catch하는 이유는 예외의 발생 이유가 오버플로우 임을 확인하기 위해서이다.
throw는 C#에서 예외를 발생시키는 키워드이다.
throw 키워드를 사용하여 명시적으로 예외를 던질 수 있다.
예외를 던지면 프로그램의 실행이 즉시 중단되고, 해당 예외를 처리하는 catch 블록으로 제어가 전달된다.
Throw를 처리할 수 있는 ArrgreateException
을 new를 이용하여 만든다.
그리고 AggregateException을 이용하여, catch메시지를 받도록 한다.
즉, if문을 이용하여 에러 메시지를 검출하는 것이다.
위 코드의 경우에는 num이 0미만인 값을 조건문에 넣을 경우 catch문으로 에러 메시지를 던지게 된다.
아규먼트 예외 또한, Exception을 이용하여 처리 가능하다.
위 코드는 값이 범위를 벗어나는지 벗어나지 않는지 검사한다.
null을 저장한 Nullable 형식의 nullNum을 이용하여, num값이 null이라면, AggregateException을 발생시킨다.
try 블록에서 AggregateException이 발생한 경우 해당 예외를 catch 블록에서 처리하는데,
catch 블록에서 AggregateException이 발생했을 때, 해당 예외의 메시지를 출력한다.
throw new AggregateException();
즉, throw new 예외문
방식으로 사용한다.
3항 연산자 형식으로 예외를 판별하고, 값을 저장할 수 있다.
다만, 이 경우 catch문이 종료되고 아래 함수를 실행하지 않는 것이 아니다.
그렇기에, 필요에 따라 적절히 if문을 이용하여 함수의 실행유무를 따져야 한다.
int a = int.MaxValue;
int b = 1;
int c = checked(a+b);
int c = checked(a+b); // 예외 발생
예를 들어, 위와 같은 코드에서 checked 키워드를 사용하면 int형 변수 a와 b를 더할 때 오버플로우가 발생하는 경우, 예외를 발생시킨다.
try~catch와 상관없이 무조건 실행하는 영역.
예외가 있든, 없든 실행된다.
try
{
// 예외가 발생할 가능성이 있는 코드
}
catch (ExceptionType ex)
{
// 예외 처리 코드
}
finally
{
// 예외 발생 여부와 관계없이 항상 실행되는 코드
}
finally 블록은 try-catch 블록 바깥에 위치하며, 예외 발생 여부와 관계없이 try 블록에서 실행된 후 항상 실행된다.
finally 블록의 주요 용도는 다음과 같다.
리소스 해제: try 블록에서 할당된 리소스를 안전하게 해제한다. 예를 들어, 파일 핸들이나 네트워크 연결 등을 닫는 작업을 수행할 수 있다.
정리 작업: try 블록에서 수행된 작업에 대한 정리 작업을 수행한다. 예를 들어, 임시 파일 삭제, 데이터베이스 트랜잭션 롤백 등을 수행할 수 있다.
리소스 반환: finally 블록에서 리소스를 반환하여 메모리 누수를 방지하고 프로그램의 안정성을 향상시킨다.
try~catch 문에서 예외처리를 할 때, 본인이 만든 함수를 이용할 수 있다.
예외 처리와 관련된 표준 라이브러리 클래스인 Exception을 오버라이딩하여, 재정의하는 것이 바로 그 방법이다.
Exception
을 상속받아서, 맴버함수를 재정의한다.
Formet형식을 바꾸는 등의 정의가 가능하다.
이를 try~catch문에서 사용한다.
base()
: Exception 클래스를 참조하는 데 사용
base.Message
는 Exception 클래스의 Message 속성을 참조. Message
는 부모 클래스의 기본 속성에 자신 클래스의 속성을 조합하여 반환
한다.사용자 지정 예외 클래스를 정의하는 이유는 애플리케이션에서 발생하는 예외를 더욱 구체적으로 설명하고, 예외 처리를 더욱 세분화하여 관리할 수 있기 때문
이를 통해 예외 처리의 정확성과 유지 보수성을 높일 수 있다
StackTrace : 어느 소스에서 에러가 났는지 확인할 수 있다.
When
키워드를 이용하면 if문처럼 자신이 원하는 특정 기능을 넣을 수 있음(조건 삽입)
when이 아닌 catch문 내부
에서 if문을 사용하여 코드를 쓸 수도 있다.
예외처리를 아주 꼼꼼하게 하여, 방어적이고 안정적인 코드를 만드는 것은
좋은 코드가 맞다.
하지만, try~catch를 너무 빈번하게 넣으면,
컴파일러가 코드를 읽고 체크할 때. 퍼포먼스가 떨어지는 문제점이 발생할 수 있다.
현업에서는 꼭 필요한 부분에서만 쓰이는 것이 추천된다.