1. 예외처리
위의 Parse()메서드를 설명할 때 이미 Runtime에러가 발생하는 경우를 봤었는데 이런 경우를 '예외가 발생했다.'라고도 표현합니다. 예외가 발생하면 try ~ catch를 사용하는 경우 에러를 제어할 수 있는 여지가 주어지지만 그렇지 않다면 stack trace를 포함한 예외 관련 메시지를 출력하고 Application의 동작은 중지됩니다.
try {
string s = "abc";
int i = int.Parse(s);
}
catch {
}
예제에서처럼 try ~ catch는 예외가 발생할 수 있는 코드 전체를 try { } 안에서 실행하도록 할 수 있으며 예외가 발생되는 경우만 catch { } 내부로 처리가 이루어지게 됩니다. 위에서 'Unhandled exception'가 발생하고 처리가 중단되는 것 과는 다르게 예외에 대한 메시지 없이 Application의 처리는 계속 진행될 수 있습니다.
catch안에서는 예외에 대한 Type을 적절히 파악하기 위해서 System.Exception을 catch안에서 사용할 수 있습니다.
try {
string s = "abc";
int i = int.Parse(s);
}
catch (System.Exception ex) {
Console.WriteLine($"{ex.GetType()} - {ex.Message}");
}
//System.FormatException - Input string was not in a correct format.
혹은 예외가 발생할 수 있는 Type이 명확하다면 해당 Type을 직접 지정해 줄 수도 있습니다.
try {
string s = "abc";
int i = int.Parse(s);
}
catch (System.FormatException) {
Console.WriteLine("문자열 형식이 잘못되었습니다.");
}
catch (System.Exception ex) {
Console.WriteLine($"{ex.GetType()} - {ex.Message}");
}
System.Exception은 모든 예외 형식에서 상속받는 가장 상위의 예외 형식이며 System.FormatException이후에 System.Exception을 다시 남겨두는 이유는 System.FormatException 이외에 다른 예외가 발생하는 경우를 대비하기 위한 것입니다.
● filter 적용
try ~ catch에서 catch는 다음과 같이 when키워드를 사용해 filter를 적용할 수 있습니다.
string s = "abc";
try {
int i = int.Parse(s);
}
catch (System.FormatException) when (s.Trim() == "abc") {
Console.WriteLine("abc는 정수로 변환될 수 없습니다.");
}
catch (System.Exception ex) {
Console.WriteLine($"{ex.GetType()} - {ex.Message}");
}
//abc는 정수로 변환될 수 없습니다.
2. 오버플로우(overflow)
어떤 값이 특정 변수가 담을 수 있는 값의 범위를 넘어서게 되면 이것을 우리는 오버플로우(overflow)라고 표현합니다. 오버플로우가 발생하면 별다른 예외는 발생하지 않고 해당 변수는 자신의 Type에서 가질 수 있는 최솟값으로 초기화됩니다.
int i = int.MaxValue; //int의 최대값으로 설정
Console.WriteLine(i); //2147483647
++i; //오버플로우
Console.WriteLine(i); //-2147483648
예외를 발생시키지 않는 건 성능 문제인데 이를 방지하고 오버플로 우발 생시 예외를 일으키려면 필요한 구문 전체를 checked로 감싸줄 수 있습니다.
checked {
int i = int.MaxValue; //int의 최대값으로 설정
Console.WriteLine(i); //2147483647
++i; //오버플로우
Console.WriteLine(i);
}
//Unhandled exception. System.OverflowException: Arithmetic operation resulted in an overflow.
// at Program.<Main>$(String[] args) in C:\Users\Administrator\Downloads\csharp\Program.cs:line 12
checked를 try ~ catch와 혼동해서는 안됩니다. overflow예외는 기본적으로는 예외 자체가 발생하지 않으므로 try ~ catch로도 잡아낼 수 없습니다. catch로 잡아내려면 checked를 감싸고 난 후 해당 구문 자체를 try ~ catch안에 배치해야 합니다.
try {
checked {
int i = int.MaxValue; //int의 최대값으로 설정
Console.WriteLine(i); //2147483647
++i; //오버플로우
Console.WriteLine(i);
}
}
catch (OverflowException)
{
Console.WriteLine("오버플로우 발생");
}
//오버플로우 발생
위에서 언급한 checked와 예제는 runtime에서의 overflow동작 와 이를 제어하기 위한 것입니다. 그러나 구문 자체만 명확하다면 overflow는 runtime이 아닌 compile에서 overflow예외를 감지할 수 있습니다.
이런 경우 예외를 발생시키지 않게 하려면 unchecked를 사용할 수 있습니다. unchecked는 compile time에서 overflow예외를 발생시키지 않도록 합니다.
unchecked {
int i = int.MaxValue + 1;
}
'.NET > C#' 카테고리의 다른 글
[C#] C#과 OOP(Object-Oriented Programming) - 2. 클래스 라이브러리 (Class library) (0) | 2022.06.24 |
---|---|
[C#] C#과 OOP(Object-Oriented Programming) - 1. 객체지향프로그래밍 개념 (0) | 2022.06.24 |
[C#] 형변환 (0) | 2022.06.24 |
[C#] 흐름제어 (0) | 2022.06.24 |
[C#] 연산자 (0) | 2022.06.24 |