Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

final, finally และ finalize ใน C#

C# ไม่มีคีย์เวิร์ด final เหมือน Java — ใช้คีย์เวิร์ดอื่นแทนตามบริบท

1. final (Java) → sealed (C#)

ใช้ sealed เพื่อห้าม Override Method หรือ ห้าม Inherit Class

Sealed Method

class Base {
    public virtual void Display() { Console.WriteLine("Base"); }
}

class Derived : Base {
    public sealed override void Display() { // Sealed — ลูกคลาส Override ไม่ได้
        Console.WriteLine("Derived (Sealed)");
    }
}

class Further : Derived {
    // public override void Display() { } // ❌ Compile Error
}

Sealed Class

public sealed class FinalClass { // ไม่สามารถ Inherit ได้
    public void Method() { }
}

2. finally (Try-Catch-Finally)

Block ที่ทำงาน เสมอ ไม่ว่าจะมี Exception หรือไม่ — ใช้สำหรับ Cleanup (Close File, Release Lock, Dispose)

FileStream fs = null;
try {
    fs = new FileStream("test.txt", FileMode.Open);
    // อ่านไฟล์...
}
catch (IOException ex) {
    Console.WriteLine("Error: " + ex.Message);
}
finally {
    fs?.Dispose(); // ทำงานเสมอ แม้มี Exception หรือ Return
}

// Better: using Statement (Auto Dispose)
using (var fs = new FileStream("test.txt", FileMode.Open)) {
    // ...
} // fs.Dispose() เรียกอัตโนมัติที่นี่

3. Finalize (Destructor / Finalizer)

Method สำหรับ Cleanup Unmanaged Resources (File Handles, Database Connections, Native Memory) — เรียกโดย Garbage Collector (Non-deterministic)

Syntax (Destructor Syntax)

class ResourceHolder {
    private IntPtr _nativeHandle; // Unmanaged Resource
    
    public ResourceHolder() {
        _nativeHandle = NativeMethods.Allocate();
    }
    
    // Finalizer (Destructor) — เรียกโดย GC
    ~ResourceHolder() {
        // Cleanup Unmanaged Only!
        if (_nativeHandle != IntPtr.Zero) {
            NativeMethods.Free(_nativeHandle);
            _nativeHandle = IntPtr.Zero;
        }
    }
    
    // IDisposable Pattern (Recommended)
    public void Dispose() {
        Dispose(true);
        GC.SuppressFinalize(this); // ป้องกัน Finalizer รันซ้ำ
    }
    
    protected virtual void Dispose(bool disposing) {
        if (_nativeHandle != IntPtr.Zero) {
            NativeMethods.Free(_nativeHandle);
            _nativeHandle = IntPtr.Zero;
        }
        if (disposing) {
            // Dispose Managed Resources Here
        }
    }
}

Comparison Table

ConceptJavaC#Purpose
Prevent Overridefinal methodsealed overrideInheritance Control
Prevent Inheritfinal classsealed classInheritance Control
Constantfinal variablereadonly / constImmutability
Guaranteed CleanupfinallyfinallyResource Cleanup (Deterministic)
GC Cleanupfinalize()~ClassName() (Finalizer)Unmanaged Resource Cleanup (Non-deterministic)

Best Practices

  • ใช้ using / IDisposable แทน Finalizer — Deterministic, Predictable
  • Finalizer ใช้เฉพาะ Unmanaged Resources — ไม่ควร Touch Managed Objects (อาจ Finalized แล้ว)
  • Implement IDisposable + Finalizer Pattern (Dispose Pattern) ถ้ามี Unmanaged Resources
  • GC.SuppressFinalize(this) ใน Dispose() เพื่อประสิทธิภาพ