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

Singleton Pattern ใน C#: การสร้าง Instance เดียว

ภาพรวม

Singleton Pattern รับประกันว่าคลาสมี instance เพียงตัวเดียวตลอดอายุของโปรแกรม และให้การเข้าถึง instance นั้นๆ แบบ global

รูปแบบที่แนะนำใน C# สมัยใหม่ (Thread-safe, Lazy)


public sealed class Singleton {
    // Lazy initialization + thread-safe โดยค่าเริ่มต้น
    private static readonly Lazy<Singleton> _instance =
        new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance => _instance.Value;

    private Singleton() { } // Private constructor

    public void Display() {
        Console.WriteLine("Singleton instance called.");
    }
}

// การใช้งาน
Singleton.Instance.Display();

รูปแบบอื่นๆ

1. Eager Initialization (Simple, Thread-safe)


public sealed class Singleton {
    public static readonly Singleton Instance = new Singleton();
    private Singleton() { }
}

2. Double-Check Locking (Manual, สำหรับ .NET เก่า)


public sealed class Singleton {
    private static Singleton _instance;
    private static readonly object _lock = new object();

    public static Singleton Instance {
        get {
            if (_instance == null) {
                lock (_lock) {
                    if (_instance == null) {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }
    private Singleton() { }
}

4. Nested Class (Lazy, Thread-safe ไม่ต้องใช้ Lazy<T>)


public sealed class Singleton {
    private Singleton() { }

    public static Singleton Instance => Nested.Instance;

    private class Nested {
        static Nested() { }
        internal static readonly Singleton Instance = new Singleton();
    }
}

การทดสอบ


class Demo {
    public static void Main() {
        Singleton s1 = Singleton.Instance;
        Singleton s2 = Singleton.Instance;
        Console.WriteLine(s1 == s2); // True
    }
}

ผลลัพธ์


True

แนวทางปฏิบัติ

  • ใช้ sealed ป้องกันการสืบทอด
  • ใช้ private constructor ป้องกันการ new จากภายนอก
  • ใน .NET 4+ ใช้ Lazy<T> เป็นวิธีที่ง่ายและปลอดภัยที่สุด
  • หลีกเลี่ยง static constructor ที่ซับซ้อน