C# 프로그래밍 - CH10 예외 처리

sookyeong·2022년 3월 30일
0

예외 처리

프로그램이 실행되는 동안 문제가 발생하면 프로그램이 자동으로 중단됨

이렇게 실행 중에 발생한 오류를 예외(Exception)라고 부름

이런 오류를 대처할 수 있게 하는 것을 예외 처리(Exception Handling)라고 부름

반면 아예 프로그램이 컴파일조차 안 되게 하는 프로그래밍 언어의 문법적인 오류를 컴파일 시점 오류(Compile-time Error) 또는 문법 오류(Syntax Error)라고 함

예외는 두 가지 방법으로 처리함

  1. 기본 예외 처리

  2. 고급 예외 처리


기본 예외 처리

예외가 발생하지 않게 사전에 해결하는 것

다음은 IndexOutOfRangeException 을 기본 예외 처리하는 예제임

static void Main(string[] args)
{
    string[] array = { "가", "나" };
    Console.Write("숫자를 입력해주세요: ");
    int input = int.Parse(Console.ReadLine());
    Console.WriteLine("입력한 위치의 값은 '" + array[input] + "' 입니다.");
}
Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.

배열의 길이를 확인해서 입력된 값이 배열의 길이를 넘으면, 잘못되었다고 알려줌 (기본 예외 처리)

static void Main(string[] args)
{
    string[] array = { "가", "나" };
    Console.Write("숫자를 입력해주세요: ");
    int input = int.Parse(Console.ReadLine());

    if (input < array.Length)
    {
        Console.WriteLine("입력한 위치의 값은 '" + array[input] + "' 입니다.");
    }
    else
    {
        Console.WriteLine("인덱스 범위를 넘었습니다.");
    }
}

고급 예외 처리

try 키워드, catch 키워드, finally 키워드로 예외를 처리하는 방법

이를 try catch finally 구문이라고 부름

try
{
    // 예외 발생 시
}
catch (Exception exception)
{
    // 여기서 처리함
}
finally
{
    // 여기는 무조건 실행함
}

catch 구문 또는 finally 구문이 필요하지 않다면, 해당 부분을 생략하고 사용할 수 있음

다음은 FormatException 을 고급 예외 처리하는 예제임

static void Main(string[] args)
{
    Console.Write("입력: ");
    string input = Console.ReadLine();

    int index = int.Parse(input);
    Console.WriteLine("입력 숫자: " + index);
}
Unhandled exception. System.FormatException: Input string was not in a correct format.

try catch finally 구문을 사용해 예외를 처리함 (고급 예외 처리)

static void Main(string[] args)
{
    Console.Write("입력: ");
    string input = Console.ReadLine();

    try
    {
        int index = int.Parse(input);
        Console.WriteLine("입력 숫자: " + index);
    }
    catch (Exception exception)
    {
        Console.WriteLine("예외가 발생했습니다.");
        Console.WriteLine(exception.GetType());
    }
    finally
    {
        Console.WriteLine("프로그램이 종료되었습니다.");
    }
}

finally 구문의 사용 여부에 따라 결과가 달라지는 경우

  1. catch 구문 내부에서 return 키워드를 만날 때

  2. catch 구문 내부에서 try catch 구문을 사용했는데 break 또는 continue 키워드를 만날 때

어떠한 상황이 되어도 finally 구문은 무조건 실행하고 끝낸다는 규칙 때문임

또한 중간에 finally 구문을 벗어나는 키워드들은 사용할 수 없음 (ex.return)


예외 객체

어떤 예외가 발생했는지와 관련된 정보를 전달해주기 위해 사용함

예외 객체는 다음과 같이 catch 구문의 괄호 안에 들어있는 변수를 나타냄

try
{

}
catch (Exception exception)     // Exception 클래스의 인스턴스로 예외 객체라고 부름
{

}

예외 객체에서 정보 추출

static void Main(string[] args)
{
    Console.Write("입력: ");
    string input = Console.ReadLine();

    try
    {
        int index = int.Parse(input);
        Console.WriteLine("입력 숫자: " + index);
    }
    catch (Exception exception)
    {
        Console.WriteLine("예외가 발생했습니다.");
        Console.WriteLine(exception.GetType());
        Console.WriteLine(exception.Message);
        Console.WriteLine(exception.StackTrace);
    }
}

예외 객체를 사용한 예외 구분

try catch 구문을 사용할 때 catch 구문을 여러 개 사용하여 예외에 따라 서로 다른 처리를 할 수 있음

try
{

}
catch (<예외1>)
{

}
catch (<예외2>)
{

}
static void Main(string[] args)
{
    Console.Write("입력: ");
    try
    {
        string input = Console.ReadLine();
        int[] array = { 52, 273, 32, 103 };
        
        int index = int.Parse(input);
        Console.WriteLine("입력 숫자: " + index);
        Console.WriteLine("배열 요소: " + array[index]);
    }
    catch (FormatException exception)
    {
        Console.WriteLine("FormatException 발생");
        Console.WriteLine(exception.GetType() + "이 발생했습니다.");
    }
    catch (IndexOutOfRangeException exception)
    {
        Console.WriteLine("IndexOutOfRangeException 발생");
        Console.WriteLine(exception.GetType() + "이 발생했습니다.");
    }
}
입력: ㅇㅅㅇ
FormatException 발생
System.FormatException이 발생했습니다.
입력: 100
입력 숫자: 100
IndexOutOfRangeException 발생
System.IndexOutOfRangeException이 발생했습니다.

예외 강제 발생

throw new Exception();

예외를 강제로 발생시킬 때는 throw 키워드를 사용하며, throw 키워드 뒤에는 Exception 클래스의 인스턴스를 입력함

무조건적으로 예외 던지기

class Program
{
    static void Main(string[] args)
    {
        throw new Exception();
    }
}
Unhandled exception. System.Exception: Exception of type 'System.Exception' was thrown.

강제로 던진 예외의 예외 처리하기

class Program
{
    static void Main(string[] args)
    {
        try
        {
            throw new Exception();
        }
        catch (Exception exception)
        {
            Console.WriteLine("예외가 발생했습니다.");
        }
    }
}
예외가 발생했습니다.

Box 클래스 예외 관련 구현

class Program
{
    class Box
    {
        private int width;
        public int Width
        {
            get { return width; }
            set
            {
                if (value > 0) { width = value; }
                else { throw new Exception("너비는 자연수를 입력해주세요."); }
            }
        }

        private int height;
        public int Height
        {
            get { return height; }
            set
            {
                if (value > 0) { height = value; }
                else { throw new Exception("높이는 자연수를 입력해주세요."); }
            }
        }

        public Box(int width, int height)
        {
            Width = width;
            Height = height;
        }

        public int Area() { return this.width * this.height; }
    }

    static void Main(string[] args)
    {
        Box box = new Box(-10, -20);
    }
}
Unhandled exception. System.Exception: 너비는 자연수를 입력해주세요.

사용자 정의 예외

class CustomException : Exception
{
    public CustomException(string message) : base(message)  // 부모 생성자 호출
    {

    }
}

class Program
{
    static void Main(string[] args)
    {
        try
        {
            throw new CustomException("사용자 정의 예외");
        }
        catch (CustomException exception)
        {
            Console.WriteLine(exception.Message);
        }
    }
}
사용자 정의 예외
profile
actions speak louder than words

0개의 댓글