C# - 예외 처리

MothorMoth·2024년 4월 27일

C#

목록 보기
14/17
post-thumbnail

예외 처리

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

1. 예외 처리의 필요성과 장점

  • 예외 상황에 대비하여 프로그램을 안정적으로 유지하는 데 도움을 준다.

  • 오류 상황을 적절히 처리하고, 프로그램의 실행을 계속할 수 있다.

  • 프로그램의 안정성을 높이고 디버깅을 용이하게 한다.

2. 예외 처리 구현

2.1 try - catch

  • try 블록에서 예외가 발생할 수 있는 코드를 작성하고, catch 블록에서 예외를 처리한다.
try
{
    // 예외가 발생할 수 있는 코드
}
catch (ExceptionType ex)
{
    // ExceptionType에 해당하는 예외 처리
}

2.2 다중 catch 블록

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

  • catch 블록은 위에서부터 순서대로 실행되며, 상속 관계에 있는 경우 상위 예외 타입의 catch 블록이 먼저 실행된다.

try
{
    // 예외가 발생할 수 있는 코드
}
catch (ExceptionType1 ex)
{
    // ExceptionType1에 해당하는 예외 처리
}
catch (ExceptionType2 ex)
{
    // ExceptionType2에 해당하는 예외 처리
}

2.3 finally 블록

  • finally 블록은 예외 발생 여부와 상관없이 항상 실행되는 코드 블록이며, 생략할 수도 있다.
try
{
    // 예외가 발생할 수 있는 코드
}
catch (ExceptionType1 ex)
{
    // ExceptionType1에 해당하는 예외 처리
}
catch (ExceptionType2 ex)
{
    // ExceptionType2에 해당하는 예외 처리
}
finally
{
    // 예외 발생 여부와 상관없이 항상 실행되는 코드
}

3. 예외 유형

System.Exception 클래스에서 파생되며, 다양한 예외들이 있어 각기 다른 오류 상황을 나타낸다.

  • System.Exception: 모든 예외의 기본 클래스. 일반적으로 특정한 예외를 잡지 못했을 때 사용된다.

  • System.NullReferenceException: 객체가 null일 때, 객체의 멤버에 접근하려고 시도할 때 발생

  • System.IndexOutOfRangeException: 배열, 리스트 등의 인덱스가 범위를 벗어날 때 발생

  • System.FormatException: 데이터의 형식이 잘못되었을 때 발생

  • System.IO.IOException: 입출력 작업 중 오류가 발생할 때 발생

  • System.InvalidOperationException: 객체의 현재 상태에서 메서드 호출이 유효하지 않을 때 발생

  • System.ArgumentException: 메서드에 잘못된 인자를 전달했을 때 발생

    • System.ArgumentNullException: null 인자가 허용되지 않는 메서드에 null이 전달될 때 발생

    • System.ArgumentOutOfRangeException: 인자가 허용된 범위를 벗어날 때 발생

  • System.DivideByZeroException: 0으로 나눌 때 발생

  • System.OutOfMemoryException: 사용 가능한 메모리가 부족하여 새 객체를 할당할 수 없을 때 발생

  • System.StackOverflowException: 스택 오버플로우가 발생했을 때 발생

  • System.TimeoutException: 작업이 설정된 시간 내에 완료되지 않을 때 발생

4. 예외 객체

  • catch 블록에서는 예외 객체를 사용하여 예외에 대한 정보를 액세스할 수 있다.

  • 예외 객체가 제공하는 몇 가지 속성
    1. Message: 오류에 대한 설명을 제공하는 문자열

    2. StackTrace: 예외가 발생한 코드의 호출 스택 정보 제공

    3. InnerException: 현재 예외를 발생시킨 또 다른 예외 객체가 있을 경우, 그 예외 객체를 참조

try
{
    // 예외가 발생할 수 있는 코드
}
catch (FormatException ex)
{
    // FormatException에 해당하는 예외 처리
    Console.WriteLine("형식 오류가 발생했습니다.");
    Console.WriteLine("오류 메시지: " + ex.Message);
    Console.WriteLine("스택 추적: " + ex.StackTrace);
}
catch (OverflowException ex)
{
    // OverflowException에 해당하는 예외 처리
    Console.WriteLine("숫자 오버플로우가 발생했습니다.");
    Console.WriteLine("오류 메시지: " + ex.Message);
    Console.WriteLine("스택 추적: " + ex.StackTrace);
    if (ex.InnerException != null)
    {
        Console.WriteLine("내부 예외: " + ex.InnerException.Message);
    }
}
finally
{
    // 예외 발생 여부와 상관없이 항상 실행되는 코드
}

5. 사용자 정의 예외

  • 필요에 따라 Exception 클래스를 상속받아 추가적인 기능이나 정보를 제공할 수 있는 사용자 정의 예외 클래스를 작성할 수 있다.
// 사용자 정의 예외 클래스
public class CustomException : Exception
{
    // 예외 메시지를 기본 클래스로 전달하는 생성자
    public CustomException(string message) : base(message)
    {

    }
}

// 사용자 정의 예외 클래스 사용
try
{
    // 예외가 발생할 수 있는 코드
}
catch (CustomException ex)
{
    // CustomException에 해당하는 예외 처리
    Console.WriteLine(ex.Message); // 에러 메시지 출력
}

// 에러가 발생하면 에러 메시지 출력

6. 예외 처리 사용 예제

  • 숫자 나누기 예외 처리
try
{
    int result = 10 / 0;  // 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);
}
  • 다양한 사용 예제
// 플레이어 이동
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);
    // 예외에 대한 추가 처리
}

0개의 댓글