C#에서 finally 키워드는 예외가 발생하든 발생하지 않든 반드시 실행되어야 하는 코드 블록을 정의할 때 사용됩니다. 대표적인 활용 사례로 파일 처리를 들 수 있습니다. 파일을 열었다면 작업 도중 예외가 발생했는지 여부와 관계없이 반드시 파일을 닫아야 리소스 누수를 방지할 수 있기 때문입니다.
finally 블록이 필요한 이유
try-catch 구문만으로도 예외를 처리할 수 있지만, catch 블록으로 제어가 넘어가면 그 이후의 정리(clean-up) 코드가 실행되지 않을 수 있습니다. finally 블록에 코드를 작성하면 다음과 같은 이점이 있습니다.
- 예외 발생 여부와 무관하게 항상 실행됨을 보장받습니다.
- 파일 스트림 닫기, 데이터베이스 연결 해제 등 리소스 정리 작업을 안전하게 처리할 수 있습니다.
구문(Syntax)
try-catch-finally의 기본적인 구문은 다음과 같습니다.
try {
// 예외를 유발할 수 있는 문장
} catch( ExceptionName e1 ) {
// 오류 처리 코드
} catch( ExceptionName e2 ) {
// 오류 처리 코드
} catch( ExceptionName eN ) {
// 오류 처리 코드
} finally {
// 반드시 실행될 문장
}예제
다음은 finally 블록의 동작을 확인하는 간단한 예제입니다. 0으로 나누기를 시도하여 DivideByZeroException이 발생하지만, finally 블록은 여전히 실행되는 것을 볼 수 있습니다.
using System;
public class Demo {
int result;
Demo() {
result = 0;
}
public void division(int num1, int num2) {
try {
result = num1 / num2;
} catch (DivideByZeroException e) {
Console.WriteLine("Exception caught = {0}", e);
} finally {
Console.WriteLine("Result = {0}", result);
}
}
public static void Main(string[] args) {
Demo d = new Demo();
d.division(100, 0);
}
}실행 결과
위 프로그램을 실행하면 다음과 같은 출력 결과를 얻을 수 있습니다.
Exception caught = System.DivideByZeroException: Attempted to divide by zero.
at Demo.division(Int32 num1, Int32 num2) in d:\Windows\Temp\n0kebv45.0.cs:line 11
Result = 0정리
이 예제에서 알 수 있듯이, try 블록에서 DivideByZeroException 예외가 발생하여 catch 블록이 먼저 실행된 후, 마지막에 finally 블록이 실행되어 "Result = 0"이 출력됩니다. 만약 예외가 발생하지 않았더라도 finally 블록은 동일하게 실행됩니다.
참고로 최신 C#에서는 이러한 리소스 정리 패턴을 더욱 간결하게 표현할 수 있는 using 문도 제공되므로, IDisposable 객체를 다룰 때는 using 문을 함께 활용하는 것이 좋습니다.