[C# Basic] 예외처리

업데이트:

이번에는 C#의 예외처리에 대해 알아보자.


* 예외처리?
  • 프로그래머가 생각하는 시나리오에서 벗어나는 사건을 예외라 한다.
  • 예외가 프로그램의 오류나 다운으로 이어지지 않도록 하는 방어적 코딩의 개념으로 예외처리가 있다.
* try ~ catch 로 예외처리
try{
    // 실행하고자 하는 코드
}
catch(IndexOutOfRangeException e){  // 인덱스 범위 초과 오류 발생시
    // 예외 발생시 처리
}
catch(예외객체2){
    // 예외 발생시 처리
}
  • try 절의 코드블록에는 예외가 없는 경우 실행될 코드가 들어가고 catch 절에는 예외 발생시의 처리 코드가 들어간다.
  • catch절의 예외 객체와 예외의 형식이 일치해야 해당 catch 절로 들어갈 수 있다.
  • catch절은 여러개가 될 수 있다.
* System.Exception 클래스
  • System.Exception 클래스는 모든 예외의 기반 클래스이다. C#의 모든 예외 클래스는 반드시 해당 클래스를 상속받아야 한다.
  • 따라서 catch 절에서 Exception 형식의 예외를 받는다면 모든 예외를 다 처리할 수 있게 된다.
  • 예외 상황에 따라 섬세한 처리가 필요한 경우 Exception 형식으로 처리하면 안되고 더 세분화된 클래스로 처리해야 한다.
* 예외 던지기
try{
    if(true){
    	throw new Exception("예외가 발생했습니다");  // throw 문을 통해 예외 객체를 catch로 던진다.
    }
}
catch(Exception e){
    Console.WriteLine(e.Message);
}
  • throw문을 통해 예외를 catch절로 던질 수 있다.
  • C# 7.0부터는 throw를 식(expression)으로도 사용할 수 있도록 개선되었다. 따라서 아래와 같은 코딩이 가능하다.
int a = b ?? throw new ArgumentNullException();  // b가 null이면 예외 발생
* try ~ catch, finally
try{
    // 실행할 코드
}
catch(Exception e){
    // 예외 발생시 처리
}
finally{
    // 예외가 나든 안나든 마지막에 실행할 코드
}
  • try 블록에서 코드 실행중 예외가 발생하면 catch절로 바로 건너뛴다. 이러한 경우 try 절의 자원해제와 같이 중요한 코드를 실행하지 못할 수 있다.
  • 이 경우 finally 절을 사용할 수 있다. finally 절은 try ~ catch 문의 마지막에 사용한다.
  • 자원해제와 같이 꼭 실행되어야 하는 코드는 finally 절에 넣어두면 된다.
  • try절 안에 return이나 throw문이 있더라도 finally절은 항상 실행된다.
  • finally절 안에서 또 예외가 발생하면 이때는 이 예외를 받아주는 코드가 없으므로 처리되지 않은 예외가 된다. finally 절 안의 내용을 다시 한번 try ~ catch 로 감싸는 방법도 있다.
* 사용자 정의 예외 클래스 만들기
class BonoException : Exception {
    // 생성자 및 프로퍼티 등 정의
}
  • 모든 예외 객체는 System.Exception 클래스로부터 파생되어야 한다.
  • Exception 클래스를 상속받기만 하면 새로운 예외클래스를 만들 수 있다.
* 예외 필터하기
class BonoException : Exception{  // 예외 클래스 생성
    public int ErrorNo{get; set;}  // 예외 클래스의 프로퍼티
}

//...

try{
    int num = 1;
    
    if(num < 5){
        throw new BonoException(){ErrorNo = num};  // num이 5보다 작으면 예외 발생
    }
}
catch(BonoException e) when (e.ErrorNo < 2){  // 5보다 작아서 예외가 발생했지만 ErrorNo가 2보다 작을때만 해당 catch절을 타도록 함
    Console.WriteLine("ErrNo는 5보다 작을때 오류가 나지만 여기서는 2보다 작을때만 처리");
}
  • C# 6.0부터 catch절이 받아들일 예외 객체에 제약조건을 걸 수 있는 예외 필터 기능이 도입되었다.
  • catch() 문 뒤에 when 키워드를 이용해 제약조건을 명시하면 된다. (when을 if라고 생각하면서 이해하면 쉽다.)
* 예외처리에 대해..
  • 예외처리는 실제 로직과 문제 발생시 이를 처리하는 코드를 분리시켜 코드를 간결하게 만들어준다.
  • 또한 예외 객체의 StackTrace 프로퍼티를 통해 문제가 발생한 부분의 소스코드 위치를 알려줌으로써 디버깅이 용이해진다.
  • 또한 여러 문제점을 하나로 묶거나 종류별로 정리해주는 효과가 있다.
  • 예외처리를 사용한 코드는 작성하기도 쉽고, 읽기도 쉽다는 장점이 있다.

카테고리:

업데이트: