ภาพรวม
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 ที่ซับซ้อน