프로그램 실행 중 예상치 못한 오류가 발생했을 때, 이를 처리하지 않으면 프로그램이 중단될 수 있습니다. 예외 처리는 이러한 상황에서 프로그램의 안정성을 유지하고, 적절한 대처를 할 수 있도록 돕는 기법입니다. 예외의 개념과 중요성, try-catch-finally 구문, throw 키워드로 예외 발생시키기, 사용자 정의 예외 클래스 만들기를 다룹니다.
예외의 개념과 중요성
**예외(Exception)**란 프로그램 실행 중 발생하는 예기치 않은 상황(오류)입니다. 예를 들어, 배열의 범위를 벗어난 접근, null 참조, 파일 읽기 실패 등이 예외에 해당합니다. 이러한 오류를 처리하지 않으면 프로그램이 중단될 수 있으므로, 예외 처리를 통해 오류를 관리하고 프로그램을 안정적으로 실행할 수 있도록 해야 합니다.
예외 처리의 주요 목적
- 프로그램 중단 방지: 예외 상황에서도 프로그램이 정상적으로 실행되도록 합니다.
- 오류 디버깅: 예외 메시지를 통해 오류 원인을 파악할 수 있습니다.
- 사용자 경험 개선: 사용자에게 적절한 오류 메시지를 제공하여 혼란을 줄입니다.
예외 발생 예제
using System;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3 };
// 배열 범위를 초과하는 인덱스 접근 시 예외 발생
Console.WriteLine(numbers[3]); // System.IndexOutOfRangeException 발생
}
}
위 코드에서 배열의 범위를 벗어난 인덱스를 접근하려고 하면 **IndexOutOfRangeException**이 발생합니다. 이러한 예외를 처리하지 않으면 프로그램이 중단됩니다.
try-catch-finally 구문
C#에서는 try-catch-finally 구문을 사용하여 예외를 처리합니다.
try-catch-finally의 구조
using System;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3 };
// 배열 범위를 초과하는 인덱스 접근 시 예외 발생
Console.WriteLine(numbers[3]); // System.IndexOutOfRangeException 발생
}
}
예제: 배열 범위 초과 예외 처리
using System;
class Program
{
static void Main()
{
int[] numbers = { 1, 2, 3 };
try
{
// 예외가 발생할 가능성이 있는 코드
Console.WriteLine(numbers[3]);
}
catch (IndexOutOfRangeException ex)
{
// 예외 처리 코드
Console.WriteLine("배열의 범위를 벗어났습니다.");
Console.WriteLine($"예외 메시지: {ex.Message}");
}
finally
{
// 항상 실행되는 코드
Console.WriteLine("예외 처리 완료.");
}
}
}
💡 finally 블록은 리소스 해제 작업이나 로그 기록과 같이 예외 발생 여부와 관계없이 항상 실행되어야 하는 코드를 작성할 때 유용합니다.
throw 키워드로 예외 발생시키기
throw 키워드를 사용하면 사용자 정의 예외를 발생시킬 수 있습니다. 이는 특정 조건에서 의도적으로 오류를 알리고, 호출자에게 문제를 전달할 때 유용합니다.
예제: 나누기 연산에서 0으로 나누기 예외 발생
using System;
class Program
{
static int Divide(int numerator, int denominator)
{
if (denominator == 0) // 분모가 0인 경우 예외 발생
{
throw new DivideByZeroException("0으로 나눌 수 없습니다.");
}
return numerator / denominator;
}
static void Main()
{
try
{
int result = Divide(10, 0); // 0으로 나누기 시도
Console.WriteLine($"결과: {result}");
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"예외 발생: {ex.Message}");
}
}
}
💡 throw 키워드를 사용해 예외를 발생시키면 호출된 코드가 예외를 처리할 수 있습니다. 이는 프로그램의 특정 조건에서 문제를 상위 로직으로 전달하는 데 유용합니다.
사용자 정의 예외 클래스 만들기
C#에서는 기본 제공 예외 클래스 외에도 사용자 정의 예외 클래스를 만들어 특정 상황에 맞는 예외를 처리할 수 있습니다. 사용자 정의 예외는 Exception 클래스를 상속받아 구현합니다.
사용자 정의 예외 클래스 예제
using System;
class Program
{
static int Divide(int numerator, int denominator)
{
if (denominator == 0) // 분모가 0인 경우 예외 발생
{
throw new DivideByZeroException("0으로 나눌 수 없습니다.");
}
return numerator / denominator;
}
static void Main()
{
try
{
int result = Divide(10, 0); // 0으로 나누기 시도
Console.WriteLine($"결과: {result}");
}
catch (DivideByZeroException ex)
{
Console.WriteLine($"예외 발생: {ex.Message}");
}
}
}
💡 사용자 정의 예외를 사용하면 특정한 비즈니스 로직에 맞는 오류를 처리할 수 있습니다. 예를 들어, 위 예제에서는 음수의 제곱근 계산이라는 특정 상황을 처리하기 위해 사용자 정의 예외를 사용했습니다.
예외 필터와 다중 catch 블록
예외 필터
C#에서는 when 키워드를 사용하여 예외 필터를 추가할 수 있습니다. 예외 필터는 특정 조건에 맞는 예외만 처리하도록 도와줍니다.
try
{
throw new Exception("특정 오류");
}
catch (Exception ex) when (ex.Message == "특정 오류")
{
Console.WriteLine("특정 오류만 처리합니다.");
}
다중 catch 블록
여러 유형의 예외를 처리하려면 다중 catch 블록을 사용할 수 있습니다. 예외는 가장 구체적인 순서로 처리됩니다.
try
{
int[] numbers = { 1, 2, 3 };
Console.WriteLine(numbers[3]);
}
catch (IndexOutOfRangeException ex)
{
Console.WriteLine("배열 범위를 초과했습니다.");
}
catch (Exception ex)
{
Console.WriteLine("일반적인 예외 처리: " + ex.Message);
}
💡 다중 catch 블록을 사용하면 다양한 예외 상황을 구체적으로 처리할 수 있습니다.