IDisposable과 using 문
Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 70개 중 45번째.
일부 객체는 가비지 수집기가 자동으로 정리할 수 없는 리소스, 즉 파일 핸들, 데이터베이스 연결, 네트워크 소켓을 계속 보유합니다. IDisposable 인터페이스는 이러한 리소스를 다 사용한 후 해제하는 표준 방법을 제공합니다.
클래스는 IDisposable Dispose() 메서드를 제공하여 구현합니다:
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 선언을 통해 더 깔끔한 구문을 제공합니다. 이 선언은 객체가 범위를 벗어날 때 객체를 삭제합니다:
void ProcessFile()
{
using FileHandler handler = new FileHandler();
// handler로 작업
} // 메서드가 종료될 때 Dispose() 호출됨using 문은 IDisposable을 구현하는 모든 형식과 함께 작동합니다. StreamReader, SqlConnection, HttpClient와 같은 기본 제공 클래스는 모두 이 인터페이스를 구현하므로 리소스 관리를 적절하고 안정적으로 수행할 수 있습니다.
챌린지
쉬움IDisposable 인터페이스와 using 문을 사용하여 적절한 리소스 관리를 보여 주는 데이터베이스 연결 시뮬레이터를 만들어 봅시다. 연결이 열리고 닫히는 시점을 추적하는 class를 만들고, 리소스가 항상 적절하게 해제되도록 합니다.
코드를 두 파일에 걸쳐 구성합니다:
DatabaseConnection.cs:DataAccessnamespace에IDisposable을 implements하는DatabaseConnectionclass를 create합니다. 연결은 다음과 같아야 합니다:- constructor를 통해 설정되는
ConnectionNameproperty(string, 읽기 전용)를 가집니다. - private boolean field를 사용하여 연결이 disposal되었는지 추적합니다.
- 객체가 생성될 때(constructor에서)
Connection opened: {ConnectionName}을 Print합니다. Dispose()method를 Implement하여Connection closed: {ConnectionName}을 Print합니다. 단, already disposal되지 않은 경우에만 실행합니다(double-disposal을 prevent).Executing on {ConnectionName}: {sql}을 반환하는Query(string sql)method를 가집니다.
- constructor를 통해 설정되는
Program.cs: main 파일에서 데이터베이스 연결과 함께using문을 사용하여 적절한 리소스 관리를 보여 줍니다. 연결을 create하고, Query를 실행한 다음,usingblock이 정리를 automatically 처리하도록 합니다.
두 개의 입력을 받습니다:
- 연결 이름(예:
MainDB) - 실행할 SQL Query(예:
SELECT * FROM Users)
using 문을 사용하여 연결을 create합니다. block Inside에서 Query method를 호출하고 결과를 Print합니다. using block이 ends되면 Dispose()가 automatically 호출됩니다.
예를 들어 입력이 MainDB와 SELECT * FROM Users라면 출력은 다음과 같아야 합니다:
Connection opened: MainDB
Executing on MainDB: SELECT * FROM Users
Connection closed: MainDBusing block이 ends될 때 연결이 automatically 닫힌다는 점에 주목하세요. 수동으로 Dispose()를 호출하는 것을 기억할 필요가 전혀 없습니다. 이 패턴은 block Inside에서 예외가 발생하더라도 리소스가 항상 정리되도록 합니다!
직접 해보기
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 메서드가 자동으로 호출됩니다
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8심화 OOP 개념
상속보다 합성(Composition)제네릭 (클래스 및 메서드)델리게이트와 이벤트어트리뷰트와 리플렉션IDisposable과 using 문Dependency Injection 기초직접 연습해 보세요: 온라인 C# 컴파일러