Menu
Coddy logo textTech

IDisposable과 using 문

Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 70개 중 45번째.

일부 객체는 가비지 컬렉터가 자동으로 정리할 수 없는 리소스(파일 핸들, 데이터베이스 연결, 네트워크 소켓 등)를 보유합니다. IDisposable 인터페이스는 이러한 리소스의 사용이 끝났을 때 이를 해제하는 표준 방법을 제공합니다.

클래스는 Dispose() 메서드를 제공하여 IDisposable을 구현합니다:

public class FileHandler : IDisposable
{
    private bool disposed = false;
    
    public void Dispose()
    {
        if (!disposed)
        {
            Console.WriteLine("Releasing resources...");
            disposed = true;
        }
    }
}

Dispose()를 수동으로 호출할 수도 있지만, 해당 라인에 도달하기 전에 예외가 발생하면 어떻게 될까요? using 문은 문제가 발생하더라도 정리가 수행됨을 보장합니다:

using (FileHandler handler = new FileHandler())
{
    // 핸들러를 사용하여 작업합니다
}  // 여기서 Dispose()가 자동으로 호출됩니다

최신 C#은 using 선언을 통해 더 깔끔한 구문을 제공하며, 이는 객체가 범위를 벗어날 때 객체를 해제(dispose)합니다:

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // handler 작업
}  // 메서드 종료 시 Dispose()가 호출됨

using 문은 IDisposable을 구현하는 모든 형식과 함께 작동합니다. StreamReader, SqlConnection, HttpClient와 같은 기본 제공 클래스들은 모두 이 인터페이스를 구현하므로, 적절한 리소스 관리를 간단하고 안정적으로 수행할 수 있습니다.

challenge icon

챌린지

쉬움

IDisposable 인터페이스와 using 문을 사용하여 적절한 리소스 관리를 보여주는 데이터베이스 연결 시뮬레이터를 만들어 보겠습니다. 연결이 열리고 닫히는 시점을 추적하여 리소스가 항상 올바르게 해제되도록 보장하는 클래스를 작성하게 됩니다.

코드는 두 개의 파일로 구성됩니다:

  • DatabaseConnection.cs: DataAccess 네임스페이스 안에 IDisposable을 구현하는 DatabaseConnection 클래스를 생성합니다. 이 연결 클래스는 다음을 수행해야 합니다:
    • 생성자를 통해 설정되는 ConnectionName 속성(문자열, 읽기 전용)을 가집니다.
    • 프라이빗 불리언 필드를 사용하여 연결이 해제(disposed)되었는지 여부를 추적합니다.
    • 객체가 생성될 때(생성자에서) Connection opened: {ConnectionName}를 출력합니다.
    • Dispose() 메서드를 구현하여 Connection closed: {ConnectionName}를 출력합니다. 단, 이미 해제된 경우에는 출력하지 않아야 합니다(중복 해제 방지).
    • Executing on {ConnectionName}: {sql}를 반환하는 Query(string sql) 메서드를 가집니다.
  • Program.cs: 메인 파일에서 데이터베이스 연결과 함께 using 문을 사용하여 적절한 리소스 관리를 보여줍니다. 연결을 생성하고, 쿼리를 실행하며, using 블록이 자동으로 정리를 처리하도록 합니다.

두 개의 입력을 받게 됩니다:

  • 연결 이름 (예: MainDB)
  • 실행할 SQL 쿼리 (예: SELECT * FROM Users)

using 문을 사용하여 연결을 생성하세요. 블록 내부에서 Query 메서드를 호출하고 그 결과를 출력합니다. using 블록이 끝나면 Dispose()가 자동으로 호출됩니다.

예를 들어, 입력이 MainDBSELECT * FROM Users라면 출력은 다음과 같아야 합니다:

Connection opened: MainDB
Executing on MainDB: SELECT * FROM Users
Connection closed: MainDB

using 블록이 끝날 때 연결이 어떻게 자동으로 닫히는지 확인해 보세요. Dispose()를 수동으로 호출할 필요가 없습니다. 이 패턴은 블록 내부에서 예외가 발생하더라도 리소스가 항상 정리되도록 보장합니다!

치트 시트

IDisposable 인터페이스는 가비지 컬렉터가 자동으로 정리할 수 없는 리소스(파일 핸들, 데이터베이스 연결, 네트워크 소켓 등)를 해제하는 표준 방법을 제공합니다.

클래스는 Dispose() 메서드를 제공함으로써 IDisposable을 구현합니다:

public class FileHandler : IDisposable
{
    private bool disposed = false;
    
    public void Dispose()
    {
        if (!disposed)
        {
            Console.WriteLine("Releasing resources...");
            disposed = true;
        }
    }
}

using 문은 예외가 발생하더라도 정리가 자동으로 수행되도록 보장합니다:

using (FileHandler handler = new FileHandler())
{
    // handler를 사용하여 작업 수행
}  // 여기서 Dispose()가 자동으로 호출됨

최신 C#은 using 선언을 통해 더 깔끔한 구문을 제공합니다:

void ProcessFile()
{
    using FileHandler handler = new FileHandler();
    // handler를 사용하여 작업 수행
}  // 메서드가 종료될 때 Dispose()가 호출됨

using 문은 StreamReader, SqlConnection, HttpClient와 같은 내장 클래스를 포함하여 IDisposable을 구현하는 모든 형식에서 작동합니다.

직접 해보기

using System;
using DataAccess;

class Program
{
    public static void Main(string[] args)
    {
        string connectionName = Console.ReadLine();
        string sqlQuery = Console.ReadLine();
        
        // TODO: 'using' 문을 사용하여 DatabaseConnection을 생성하세요.
        // using 블록 내부에서:
        // 1. sqlQuery를 사용하여 Query 메서드를 호출하세요.
        // 2. Query 메서드의 결과를 출력하세요.
        // using 블록이 끝나면 Dispose 메서드가 자동으로 호출됩니다.
        
    }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨