본문 바로가기

.NET/C#

[C#] try~catch~finally 구문 사용법

try~catch~finally 구문은 예외를 처리하기 위해 사용하는 구문이며 try~, catch~, finally~의 총 세 개의 절로 구성된다.

단, finally 절은 선택 사항이므로 반드시 사용해야 하는 것은 아니다.

 

1. try 절

try라는 단어에서 알 수 있듯이, 이 구문은 try { }로 감싸진 블록 내의 코드를 수행하려고 시도한다.

만약 블록 내의 코드를 수행하는 도중 예외가 발생할 경우 코드의 처리를 중단하고, 발생한 예외를 가지고 catch 절로 이동한다.

 

2. catch 절

catch 절은 예외를 받는 역할을 한다.

try
{
	double d = a / b;
}
catch
{
	Console.WriteLine("error!");
}

만약 위 코드의 try 절에서 b가 0인 경우 DivideByZeroException 예외가 발생할 것이고, 발생한 예외는 catch 절로 이동해서 catch절 내부의 문장을 수행한다.

 

catch에는 매개변수로 받을 예외의 타입을 지정하여 원하는 예외만 catch 할 수 있다.

try
{
	double d = a / b;
}
catch (DivideByZeroException ex)
{
	Console.WriteLine($"Divide by zero. ({ex.Message})");
}

위 코드에서 catch 절은 오직 DivideByZeroException이 발생한 경우에만 수행된다.

catch 절의 괄호 안에 예외의 타입과 함께 이름을 지정할 경우 예외 객체에 포함된 예외 정보를 사용할 수 있다.

 

만약 예외의 종류에 상관 없이 모든 예외를 받고 싶다면 위로 두 번째 코드처럼 catch { }와 같이 사용하면 되나, 예외 정보를 확인하고자 하는 경우 모든 예외 클래스의 최상위 클래스인 Exception으로 예외를 받으면 된다.

try
{
	double d = a / b;
}
catch (Exception ex)
{
	Console.WriteLine($"error! ({ex.Message})");
}

모든 예외는 Exception 클래스로부터 파생되므로, Exception 형식으로 catch 할 수 있다.

 

catch 절을 여러 개 사용하여 각 예외에 따라 다른 처리를 하는 것도 가능하다.

try
{
	double d = a / b;
}
catch(DivideByZeroException)
{
	Console.WriteLine("Divide by zero.");
}
catch(Exception ex)
{
	Console.WriteLine($"error! ({ex.Message})");
}

위 코드에서는 DivideByZeroException을 받는 catch 절이 있고, Exception을 받는 catch 절이 있는데, DivideByZeroException 예외가 발생한 경우에는 위쪽 catch 절의 구문이 수행되고, 그 외 다른 모든 예외는 아래쪽 catch 절에서 처리된다.

if-else if 구문처럼 위쪽에 위치한 구문에 이미 걸려서 처리되었다면 그 다음에 위치한 구문들에서 다시 한번 조건을 만족하더라도 재차 수행되지 않는다. 또한 위쪽에 위치한 catch 절부터 순차적으로 발생한 예외를 처리할 catch 절이 있는지를 검사하므로, 만약 가장 위쪽에 위치한 catch 절이 Exception 예외를 처리한다면, 아래쪽에 위치한 catch 절들은 무의미하다.

가령,

try
{
	double d = a / b;
}
catch(Exception ex)
{
	Console.WriteLine($"error! ({ex.Message})");
}
catch(DivideByZeroException)
{
	Console.WriteLine("Divide by zero.");
}

위와 같은 코드에서 DivideByZeroException catch 절은 절대 수행되지 않는다.

 

3. finally 절

finally절은 예외가 발생하지 않고 try절이 정상적으로 종료되었을 때, 또는 예외 발생하였으나 발생한 예외를 catch절에서 받아서 처리했을 때 수행된다.

double d;
try
{
	d = a / b;
    if(d == 1) throw new Exception();
}
catch(DivideByZeroException)
{
	Console.WriteLine("Divide by zero.");
    d = 0;
}
finally
{
	Console.WriteLine($"d = {d}");
}

위 코드에서 b가 0인 경우 DivideByZeroException catch 절을 수행한다.

만약 b가 0이 아니고 a / b의 결과가 1이 아닌 경우 try절이 정상적으로 종료된다.

위 두 경우 모두, 마지막으로 finally절을 수행한다.

만약 a / b의 결과가 1인 경우 Exception 예외를 throw 하도록 되어 있는데, 이러한 경우에 Exception 예외를 받을 수 있는 catch 절은 존재하지 않아 프로그램이 비정상 종료되며, finally 절은 수행되지 않는다.