| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- PS
- c#
- Unity
- Online Judge
- multi-thread
- BOJ
- C++
- Network Programming
- Data Structure
- git
- 독서
- Toy Project
- System Programming
- Today
- Total
I'm FanJae.
[20260518] C# ( Exception ) 본문
1. 정의
- 예외(Exception)는 프로그램 실행 중 발생하는 예상치 못한 오류 상황을 의미한다.
(1) 예시
- 잘못된 사용자 입력
- 파일이 존재하지 않음
- 네트워크 연결 끊김
- 배열 범위를 벗어난 접근
- null 객체 접근
- 위와 같은 상황이 발생했을 때 프로그램이 강제 종료되지 않도록 처리하는 것이 예외 처리(Exception Handling)이다.
2. 예외 처리가 필요한 이유
- 프로그램은 항상 개발자의 의도대로만 동작하지 않는다.
- 여러 가지 외부 요인 때문에 오류가 발생할 수 있다.
(1) 사용자 입력 오류
int number = int.Parse("abc");
- 숫자가 아닌 값을 입력하면 예외가 발생한다.
(2) 파일 관련 오류
public SaveData? Load() // 불러오기
{
// 파일 없으면 null 리턴
if (!File.Exists(SaveFilePath))
return null;
try
{
// 파일 전체 읽어옴
string json = File.ReadAllText(SaveFilePath);
return JsonSerializer.Deserialize<SaveData>(json);
}
catch (IOException) // 파일 입출력 자체 실패
{
return null;
}
catch (UnauthorizedAccessException) // 접근 권한 문제
{
return null;
}
catch (JsonException) // 파싱 실패
{
return null;
}
}
- 프로젝트에서 파일을 불러올 때, 파일이 없으면, 읽는 작업을 하면 안된다.
(3) 네트워크 오류
- 서버 연결 실패나 인터넷 끊김 등이 있는 경우에 대한 처리가 필요하다.
(4) 하드웨어 / 시스템 문제
- 메모리 부족이나 장치 접근 실패 등에 대한 처리가 필요하다.
3. 예외 처리를 하지 않으면 발생하는 문제
namespace ExceptionExample
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine("숫자를 입력하세요 : ");
string input = Console.ReadLine();
// 숫자가 아닌 값을 입력하면 예외 발생
int number = int.Parse(input);
Console.WriteLine($"입력한 숫자 : {number}");
Console.WriteLine("프로그램 정상 종료");
}
}
}

- 예외처리를 해주지 않으면 오류가 뜨면서 강제 종료된다.
- 이렇게 되면 사용자에게 문제점이 무엇인지 알려주기가 어렵고, 프로그램 흐름이 중단된다.
4. 사용 예시
try
{
// 예외가 발생할 가능성이 있는 코드
}
catch (예외 타입)
{
// 예외 발생 시 실행
}
finally
{
// 무조건 실행
}
(1) try
- 예외가 발생할 가능성이 있는 코드를 작성하는 영역이다.
try
{
string dat = Console.ReadLine();
int value = int.Parse(dat);
}
- 위와 같이 예외가 발생할 수 있는 코드를 try에 넣어준다.
(2) catch
-try 안에서 예외가 발생하면, 그 예외 타입과 일치하는 catch 블록이 실행된다.
try
{
string data = Console.ReadLine();
int value = int.Parse(data);
}
catch (FormatException) // 숫자 형식 관련 Exception
{
Console.WriteLine("숫자 형식이 아닙니다.");
}
catch (OverflowException) // 숫자 범위 관련 Exception
{
Console.WriteLine("숫자 범위를 초과했습니다.");
}
(3) finally
finally
{
Console.WriteLine("입력 처리를 종료합니다.");
}
- fianlly 에는 보통 반드시 실행되어야 하는 문장을 넣으면 된다.
- 예외 발생 여부와 관계 없이 반드시 실행되어야 하는 작업으로, 리소스 정리나 마무리 작업에 사용한다.
try
{
file = File.Open("test.txt", FileMode.Open);
}
catch (FileNotFoundException)
{
Console.WriteLine("파일이 존재하지 않습니다.");
}
finally
{
if(file != null)
{
file.Close();
}
}
5. 자주 발생하는 예외와 유의사항
(1) 컴파일러 생성 예외
- 아래 예외들이 실행 중 발생할 수 있는 대표적인 예외이다.
- IndexOutOfRangeException - 배열 범위 초과
- DivideByZeroException - 0으로 나눔
- NullReferenceException - null 객체 접근
- InvalidCastException - 잘못된 형 변환
- OverflowException - 숫자 범위 초과
- StackOverflowException - 재귀 과다 호출
- OutOfMemoryException - 메모리 부족
- FileNotFoundException - 파일 없음
(2) 유의사항 1. 예외 처리보다 사전 검사가 좋은 경우가 있다.
- 모든 상황을 try-catch로 처리하는 것은 좋은 방식이 아니다.
- 간단한 경우 사전에 검사하는 것이 더 효율적이다.
① 이유
- 예외가 발생하지 않으면 부담이 크지 않지만, 예외가 실제로 발생하면 아래와 같은 작업이 일어나게 된다.
- 예외 객체의 생성
- 호출 스택 정보 수집
- 적절한 catch 탐색의 과정
- 따라서, 예상하기 어려운 비정상적인 상황에 대한 처리를 try, catch에 맡겨야 한다.
② 예시
(1) 사용자 입력 검증
try
{
int number = int.Parse(input);
}
catch (FormatException)
{
Console.WriteLine("숫자를 입력하세요.");
}
- 숫자 입력 여부는 예측 가능하다. 이는 TryParse로 처리하는게 좋다.
if (int.TryParse(input, out int number))
{
Console.WriteLine(number);
}
else
{
Console.WriteLine("숫자를 입력하세요.");
}
(2) 배열 인덱스 범위 검사
try
{
Console.WriteLine(arr[index]);
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("잘못된 인덱스입니다.");
}
if (index >= 0 && index < arr.Length)
{
Console.WriteLine(arr[index]);
}
else
{
Console.WriteLine("잘못된 인덱스입니다.");
}
- 배열에서 잘못된 인덱스를 검증할 때 배열 범위 안에 있는지 미리 확인할 수 있는데, try,catch 보다 인덱스 값에 대한 if 처리가 낫다.
③ 外
NullReferenceException - if(player == null) 과 같은 null 체크
DivideByZeroException - if문으로 0으로 나눌 수 없음 처리
(3) 유의사항 2. catch로 해결 하면 안되는 예외
- 일부 예외는 발생한 시점에서 복구 가능한 상황이 아닐 수 있다.
- StackOverflowException , OutOfMemoryException 과 같은 예외가 발생한 경우, 해당 오류가 발생한 원인을 찾아야지 이를 catch로 잡는 식으로 해결하면 안된다.
6. Exception도 클래스다.
- C#에서 다뤄지는 모든 Exception 클래스는 Exception이라는 클래스를 상속 받고 있다.
public class Exception
{
public string Message; // 예외 원인 설명
public string StackTrace; // 예외가 발생한 호출 흐름
}
(1) Message
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
- Message는 무슨 문제가 발생했는지 확인할 때 사용할 수 있다.

(2) StackTrace
- StackTrace 는 예외가 발생하기까지 어떤 메서드를 거쳐왔는지 보여준다.
catch(Exception ex)
{
Console.WriteLine(ex.StackTrace);
}

- 이를 통해서 어디서 문제가 발생했는지 찾을 때 사용할 수 있다.
7. Exception 사용시 주의점
(1) 빈 catch을 사용하지 않는다.
catch
{
}
- 사용하는 것 자체는 문제가 되지 않지만, 오류 원인을 알기 어렵다.
(2) Exception을 남용하지 않는다.
catch (Exception ex)
{
}
- 모든 예외를 Exception 하나로 처리하면, 디버깅 하기가 까다로워 진다.
(3) Exception은 흐름 제어 용도가 아니다.
- 예측 가능한 오류라면 사전 검사 작업으로 처리해야한다.
8. 정리
- 예외(Exception)은 실행 중 발생하는 비정상 상황이다.
- 예외 처리는 프로그램 비정상 종료를 막기 위해 사용한다.
- try-catch-finally 구조로 처리한다.
- finally는 예외 여부와 관계 없이 반드시 실행된다.
- 모든 예외는 Exception 클래스를 상속 받는다.
- Exception은 비용이 큰 작업으로, 간단한 상황은 예외 처리 보다 사전 검사가 더 효율적이다.
※ 즉, Exception은 예상하지 못한 상황을 처리할 때 사용할 수 있다.
'Unity > Unity 초격차캠프' 카테고리의 다른 글
| [20260519] C# 정리 ( Lambda Expression ) (0) | 2026.05.19 |
|---|---|
| [20260518] Git 용어 정리 (0) | 2026.05.18 |
| [20260515] C# ( Event ) (0) | 2026.05.15 |
| [20260515] C# ( Func ) (0) | 2026.05.15 |
| [20260515] C# ( Action ) (0) | 2026.05.15 |