C# Programming

C# using ν‚€μ›Œλ“œλ‘œ λ¦¬μ†ŒμŠ€λ₯Ό μ•ˆμ „ν•˜κ²Œ κ΄€λ¦¬ν•˜λŠ” 방법(+ using μ„ μ–Έκ³Ό using λ¬Έ μ‚¬μš©μ˜ 차이)

ν”„λ‘œκ·Έλž˜λ¨Έ μ˜€μ›” 2025. 4. 25.

 

C#μ—μ„œλŠ” μ™ΈλΆ€ μžμ›(파일, λ„€νŠΈμ›Œν¬ μŠ€νŠΈλ¦Ό, DB μ—°κ²° λ“±)을 λ‹€λ£° λ•Œ λ°˜λ“œμ‹œ λͺ…μ‹œμ μΈ ν•΄μ œκ°€ ν•„μš”ν•©λ‹ˆλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ‚˜ νŒŒμΌ μž κΈˆ κ°™μ€ λ¬Έμ œκ°€ λ°œμƒν•  μˆ˜ μžˆμŠ΅λ‹ˆλ‹€. μ΄λ₯Ό λ°©μ§€ν•˜κΈ° μœ„ν•΄ C#은 IDisposable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ κ°μ²΄λ₯Ό μžλ™μœΌλ‘œ ν•΄μ œν•΄μ£ΌλŠ” using ν‚€μ›Œλ“œλ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

using ν‚€μ›Œλ“œλŠ” λ‹€μŒκ³Ό κ°™μ€ λ‘ κ°€μ§€ λ°©μ‹μœΌλ‘œ μ‚¬μš©ν•  μˆ˜ μžˆμœΌλ©°, μžμ› κ΄€λ¦¬μ™€ μ½”λ“œμ˜ μ•ˆμ •μ„± μΈ‘λ©΄μ—μ„œ λ§€μš° μ€‘μš”ν•œ μ—­ν• μ„ ν•©λ‹ˆλ‹€.

 

1️⃣ using λ¬Έ (using statement)

 

using (var stream = new FileStream("example.txt", FileMode.Open))
{
    // νŒŒμΌμ„ μ½κ±°λ‚˜ 씀
} // using 블둝이 λλ‚˜λ©΄ stream.Dispose()κ°€ μžλ™ 호좜됨

 

μ½”λ“œ λΈ”둝이 μ’…λ£Œλ˜λ©΄ Dispose()κ°€ μžλ™μœΌλ‘œ ν˜ΈμΆœλ˜μ–΄ μžμ›μ„ ν•΄μ œν•©λ‹ˆλ‹€.

μ˜ˆμ™Έκ°€ λ°œμƒν•˜λ”라도 finally λΈ”λ‘μ²˜λŸΌ μ•ˆμ „ν•˜κ²Œ μ •λ¦¬λ©λ‹ˆλ‹€.

 

 

2️⃣ using μ„ μ–Έ (C# 8.0λΆ€ν„° λ„μž…)

using var stream = new FileStream("example.txt", FileMode.Open);
// μ½”λ“œ 블둝 없이도 μ‚¬μš© κ°€λŠ₯ν•˜λ©°, λ³€μˆ˜μ˜ μŠ€μ½”ν”„κ°€ λλ‚˜λ©΄ Dispose() μžλ™ 호좜

 

보닀 κ°„κ²°ν•œ μ½”λ“œ μž‘성이 κ°€λŠ₯ν•˜λ©°, λ³€μˆ˜μ˜ μƒλͺ… μ£ΌκΈ°(scope)에 λ”°λΌ μžλ™ ν•΄μ œκ°€ μ΄λ€„μ§‘λ‹ˆλ‹€.

단, μ΄ λ°©μ‹μ€ λ³€μˆ˜κ°€ μ„ μ–Έλœ λ©”μ„œλ“œ λ‚΄μ—μ„œλ§Œ μœ νš¨ν•©λ‹ˆλ‹€.

μ „μžμ˜ κ²½μš° C# κ΅¬λ²„μ „λΆ€ν„° μ§€μ›ν–ˆμ§€λ§Œ, ν›„μžμ˜ κ²½μš°μ—λŠ” 8.0 λ²„μ „ μ΄ν›„λΆ€ν„° μ§€μ›ν•΄μ£Όκ³  μžˆμŠ΅λ‹ˆλ‹€.

ν›„μžκ°€ λ” μ΅œκ·Όμ— λ‚˜μ˜¨ ν‘œν˜„μ‹μ΄λ‹ˆ ν›„μžλ‘œ μ“°λ©΄ ν•­μƒ μ’‹μ„κΉŒμš”?

μ˜ˆμƒν•˜μ…¨λ‹€μ‹œν”Ό μ•„λ‹™λ‹ˆλ‹€.

 

 

πŸ’‘μ μ ˆν•œ using μ‚¬μš©λ²•

μ‹€μ œ ν™œμš©ν•  수 μžˆλŠ” μ½”λ“œ ꡬ쑰둜 λ³΄λ©΄μ„œ 두 κ°€μ§€μ˜ 차이점을 λŠκ»΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

βœ… 1. using λ¬Έ

class Temp : IDisposable
{
    public Temp() => Console.WriteLine("Temp 객체 생성");
    public void Dispose() => Console.WriteLine("Temp 객체 ν•΄μ œ");
}

class Program
{
    static void Main()
    {
        using (var temp = new Temp()) // -> 블둝 λ‚΄λΆ€μ—μ„œλ§Œ temp μ‚¬μš© κ°€λŠ₯
        {
            Console.WriteLine("블둝 λ‚΄λΆ€ μ‹€ν–‰");
        } // βœ… 블둝이 λλ‚˜λŠ” μ¦‰μ‹œ Dispose() 호좜됨

        Console.WriteLine("블둝 μ’…λ£Œ");
    }
}

 

using 문을 ν™œμš©ν•˜λ©΄ using 문이 끝날 λ•Œ Dispose() λ₯Ό ν˜ΈμΆœν•˜μ—¬ 객체 μ†Œλ©Έ 과정이 μ΄λ€„μ§‘λ‹ˆλ‹€. μœ„ μ˜ˆμ‹œ μ½”λ“œμ—μ„  βœ… 쀄을 μ§€λ‚˜λ©΄ λ°”λ‘œ Dispose() ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜λŠ” 것이죠.

Temp 객체 생성
블둝 λ‚΄λΆ€ μ‹€ν–‰
Temp 객체 ν•΄μ œ
블둝 μ’…λ£Œ

 

βœ… 2. using μ„ μ–Έ

class Temp : IDisposable
{
    public Temp() => Console.WriteLine("Temp 객체 생성");
    public void Dispose() => Console.WriteLine("Temp 객체 ν•΄μ œ");
}

class Program
{
    static void Main()
    {
        using var temp = new Temp();
        Console.WriteLine("λ©”μ†Œλ“œ λ‚΄λΆ€ μ‹€ν–‰");

        // βœ… temp λ³€μˆ˜λ₯Ό ν˜ΈμΆœν•œ λΈ”λŸ­ λ‚΄μ—μ„œ 계속 μ‚¬μš©ν•  수 있음
        Console.WriteLine("아직 Dispose() 호좜 μ•ˆ 됨");
    } // βœ… λ©”μ†Œλ“œ μ’…λ£Œ μ‹œ Dispose() 호좜됨
}

 

using 선언을 μ‚¬μš©ν•˜λŠ” 경우 using ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œ 블둝이 λλ‚˜μ•Όλ§Œ Dispose() ν˜ΈμΆœλ©λ‹ˆλ‹€.

Temp 객체 생성
λ©”μ†Œλ“œ λ‚΄λΆ€ μ‹€ν–‰
아직 Dispose() 호좜 μ•ˆ 됨
Temp 객체 ν•΄μ œ

 

 

눈치 λΉ λ₯΄μ‹  뢄이라면 μ œκ°€ μ–΄λ–€ 점을 말할렀고 ν•˜λŠ”μ§€ 눈치 채셨을 κ²λ‹ˆλ‹€.

 

 

 

CASE 1

class Program
{
    static void Main()
    {
        using (var conn = new SqlConnection(connectionString)) 
        {
            conn.Open();
            // DB κ΄€λ ¨ 둜직
            
        } // βœ… 블둝이 λλ‚˜λŠ” μ¦‰μ‹œ conn.Dispose() 호좜됨
        
        // 연산이 맀우 였래 κ±Έλ¦¬λŠ” μ½”λ“œ 
    }
}

 

CASE 2

class Program
{
    static void Main()
    {
        using var conn = new SqlConnection(connectionString); // DB connection λ§ΊλŠ” 둜직
        conn.Open();
        // DB κ΄€λ ¨ 둜직

        // 이후 연산이 맀우 였래 κ±Έλ¦¬λŠ” μ½”λ“œ 
        
    } // βœ… λ©”μ†Œλ“œ μ’…λ£Œ μ‹œ conn.Dispose() 호좜됨
}

 

μœ„  두 κ°€μ§€ μΌ€μ΄μŠ€λΌλ©΄ 차이가 λŠκ»΄μ§€μ‹œλ‚˜μš”? 

ν›„μžμ˜ 경우λ₯Ό ν™œμš©ν•˜κ²Œ 되면, DB 컀λ„₯μ…˜μ„ ν•΄μ œν•˜μ§€ μ•Šμ€ 채 연산이 맀우 였래 κ±Έλ¦¬λŠ” μ½”λ“œλ₯Ό μ§€λ‚˜ 블둝이 λλ‚ λ•Œ 객체 μ†Œλ©Έ 과정이 일어날 κ²ƒμž…λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ „μžμ˜ 경우 컀λ„₯μ…˜μ„ λ§Ίκ³  κ΄€λ ¨ 둜직 이후 λ°”λ‘œ μ†Œλ©Έ 과정을 거치고, κ·Έλ‹€μŒ 연산이 맀우 였래 κ±Έλ¦¬λŠ” 둜직이 μ‹€ν–‰λ©λ‹ˆλ‹€.

DB 컀λ„₯μ…˜μ€ 였래 λ¬Όκ³  있으면 μ’‹μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ 컀λ„₯μ…˜μ„ λ§Ίμ–΄μ•Όν•˜λŠ”λ°, 계속 컀λ„₯μ…˜μ„ λ¬Όκ³  μžˆλ‹€λ©΄ 컀λ„₯μ…˜ 풀에 μ—°κ²°ν•  수 μžˆλŠ” 컀λ„₯μ…˜μ΄ 남아 μžˆμ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

이와 같이 빨리 μžμ› ν•΄μ œλ₯Ό ν•΄μ€˜μ•Όν•˜λŠ” 경우 λ˜λŠ” 이후 둜직이 μ‹œκ°„ λ³΅μž‘λ„κ°€ 높은 경우 using 문을 μ‚¬μš©ν•˜μ—¬ 효율적으둜 λ¦¬μ†ŒμŠ€λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

✨마무리

DB μ»€λ„₯μ…˜μ€ GCλ§ŒμœΌλ‘œλŠ” ν•΄μ œκ°€ λ³΄μž₯λ˜μ§€ μ•ŠλŠ” λ„€νŠΈμ›Œν¬ κΈ°λ°˜μ˜ μžμ›μž…λ‹ˆλ‹€.
μ‚¬μš© ν›„ λͺ…ν™•νžˆ Close() λ˜λŠ” Dispose()ν•˜μ§€ μ•ŠμœΌλ©΄ 컀λ„₯μ…˜ ν’€ 고갈, μ„Έμ…˜ 잠금 등이 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.
μ΄λ ‡κ²Œ IDisposable을 κ΅¬ν˜„ν•œ κ°μ²΄λŠ” κ΄€λ¦¬λ˜μ§€ μ•ŠλŠ” μžμ›(unmanaged resources)을 포함할 수 μžˆμœΌλ―€λ‘œ, GC(Garbage Collector)λ§ŒμœΌλ‘œλŠ” ν•΄μ œκ°€ 보μž₯λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.


using은 μ΄λŸ¬ν•œ 문제λ₯Ό μžλ™μœΌλ‘œ λ°©μ§€ν•˜λŠ” κ°•λ ₯ν•œ λ„κ΅¬μž…λ‹ˆλ‹€. using을 μ‚¬μš©ν•˜λ©΄ μ½”λ“œκ°€ λ”μš± λͺ…ν™•ν•˜κ³  μ˜ˆμ™Έμ— μ•ˆμ „ν•˜λ©°, λ¦¬μ†ŒμŠ€ λˆ„μˆ˜λ₯Ό λ°©μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

λ¦¬μ†ŒμŠ€λ₯Ό λ‹€λ£¨λŠ” λͺ¨λ“  μ½”λ“œμ— using을 적절히 μ‚¬μš©ν•˜λ©΄, μ˜ˆμ™Έ 상황에도 κ°•μΈν•˜κ³  κΉ”λ”ν•œ μ½”λ“œλ₯Ό μœ μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 특히 파일 I/O, DB μ—°κ²°, λ„€νŠΈμ›Œν¬ 톡신 λ“±μ—μ„œλŠ” using을 μ“°λŠ” κ²ƒλ§ŒμœΌλ‘œλ„ λ§Žμ€ 버그λ₯Ό μ˜ˆλ°©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λŒ“κΈ€