C# 문법 4주차 - 예외 처리

Amberjack·2024년 1월 2일
0

C# 문법

목록 보기
25/44

⚠️ 예외 처리

🤔 예외란?

  • 프로그램 실행 중 발생하는 예기치 않은 상황
  • 프로그램의 정상적인 흐름을 방해, 오류를 야기할 수 있다.

😊 예외 처리의 필요성과 장점

  • 예외 처리는 예외 상황에 대비하여 프로그램을 안정적으로 유지하는 데 도움을 준다.
  • 예외 처리를 통해 오류 상황을 적절히 처리, 프로그램 실행을 계속할 수 있다.
  • 예외 처리는 프로그램의 안정성을 높이고 디버깅을 용이하게 한다.

▪️ 예외 처리 구현

  • C#에서는 try-catch블록을 사용하여 예외 처리를 수행한다.
  • try 블록 내에서 예외가 발생할 수 있는 코드를 작성, catch 블록에서 예외를 처리.

예시)

try
{
    // 예외가 발생할 수 있는 코드
}
catch (ExceptionType1 ex)
{
    // ExceptionType1에 해당하는 예외 처리
}
catch (ExceptionType2 ex)
{
    // ExceptionType2에 해당하는 예외 처리
}
finally
{
    // 예외 발생 여부와 상관없이 항상 실행되는 코드
}

▪️ catch 블럭의 우선순위

  • catch 블럭은 위에서부터 순서대로 실행, 예외 타입에 해당하는 첫 번째 catch 블록이 실행된다.
  • 예외 타입은 상속 관계에 있는 경우, 상위 예외 타입의 catch 블럭이 먼저 실행된다.

▪️ 다중 catch 블럭

  • 여러 개의 catch 블럭을 사용, 다양한 예외 타입을 처리할 수 있다.
  • 다중 catch 블럭을 사용하면 각각의 예외 타입에 따라 다른 예외 처리 코드를 작성할 수 있다.

▪️ 예외 객체

  • catch 블럭에서는 예외 객체를 사용하여 예외에 대한 정보를 액세스할 수 있다.
  • 예외 객체를 사용하여 예외의 타입, 메시지 등을 확인하고 처리할 수 있다.

⚠️ finally 블록

▪️ finally 블럭의 역할과 사용법

  • finally는 예외 발생 여부와 상관없이 항상 실행되는 코드 블럭.
  • finally는 예외 처리의 마지막 단계로, 예외 발생 시 정리 작업이나 리소스 해제 등의 코드를 포함할 수 있다.
  • finally는 try-catch 블럭 뒤에 작성되며, 생략할 수도 있다.

▪️ finally의 실행 시점

  1. 예외가 발생한 경우 : 예외가 발생하면 예외 처리 과정을 거친 후 finally가 실행.
  2. 예외가 발생하지 않은 경우 : 예외가 발생하지 않아도 finally는 정상 실행.

⌨️ 사용자 정의 예외

▪️ 사옹자 정의 예외 클래스 작성

  • 사용자는 필요에 따라 자신만의 예외 클래스를 작성할 수 있다.
  • 사용자 정의 예외 클래스는 Exception 클래스를 상속받아 작성하며, 추가적인 기능이나 정보를 제공할 수 있다.

▪️ 사용자 정의 예외 처리

  • 사용자 정의 예외가 발생할 경우, try-catch 블럭에서 해당 예외를 처리할 수 있다.
  • catch 블럭에서 사용자 정의 예외 타입을 명시하여 예외를 처리, 예외에 대한 적절한 처리 로직을 작성할 수 있다.

📚 예외 처리 사용 예제)

▪️ 숫자 나누기 예외 처리 : 0으로 나누기(DividByZeroException)

try
{
	int zero = 0;
    int result = 10 / zero;  // ArithmeticException 발생
    Console.WriteLine("결과: " + result);
}
catch (DivideByZeroException ex)
{
    Console.WriteLine("0으로 나눌 수 없습니다.");
}
catch (Exception ex)
{
    Console.WriteLine("예외가 발생했습니다: " + ex.Message);
}
finally
{
    Console.WriteLine("finally 블록이 실행되었습니다.");
}

▪️ 사용자 정의 예외 처리 예시)

public class NegativeNumberException : Exception
{
    public NegativeNumberException(string message) : base(message)
    {
    }
}

try
{
    int number = -10;
    if (number < 0)
    {
        throw new NegativeNumberException("음수는 처리할 수 없습니다.");
    }
}
catch (NegativeNumberException ex)
{
    Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
    Console.WriteLine("예외가 발생했습니다: " + ex.Message);
}

해당 코드에서 눈여겨 봐야할 점 :


1. NegativeNumberException이라는 사용자 정의 예외 처리 클래스를 생성할 때, Exception이라는 부모 클래스를 상속 받는다.
2. 그 후, 클래스의 생성자를 만드는데, string message를 매개변수로 받는다.
3. 이 매개변수는 뒤의 base(message)는 Initializer로, 해당 생성자가 실행되기 전에 부모 4클래스의 생성자를 먼저 실행한 뒤에 해당 생성자를 실행한다.

→ 이 코드의 경우, base(message)는 Exception의 생성자를 먼저 실행한 후, 사용자 정의 예외 클래스의 생성자가 실행되게 된다.

▪️ 게임에서 다양한 사용 예제)

// 플레이어 이동
try
{
    // 플레이어 이동 코드
    if (IsPlayerCollidingWithWall())
    {
        throw new CollisionException("플레이어가 벽에 충돌했습니다!");
    }
}
catch (CollisionException ex)
{
    // 충돌 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}


// 리소스 로딩
try
{
    // 리소스 로딩 코드
    LoadResource("image.png");
}
catch (ResourceNotFoundException ex)
{
    // 리소스가 없는 경우 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}
catch (ResourceLoadException ex)
{
    // 리소스 로딩 중 오류가 발생한 경우 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}


// 게임 상태 전이
try
{
    // 상태 전이 코드
    if (currentGameState != GameState.Playing)
    {
        throw new InvalidStateException("게임이 실행 중이 아닙니다!");
    }
    // 게임 상태 전이 실행
}
catch (InvalidStateException ex)
{
    // 상태 예외 처리
    Debug.Log(ex.Message);
    // 예외에 대한 추가 처리
}

⚠️ 예외 처리 시 주의사항!

예외 처리를 하는 목적은 우려되는 코드들을 예외 처리하기 위함이다. 그러나 try문 안에 너무 긴 코드를 넣게 되면 문제 파악하기가 어려워 예외 처리를 하기 어려워진다. 때문에 정말 우려가 되는 코드들만 넣는 것이 좋다.

0개의 댓글