Private Constructor ใช้ป้องกันการสร้าง Instance จากภายนอก ใช้ใน:
- Class ที่มีเฉพาะ Static Members (Utility Class)
- Singleton Pattern
- Factory Methods
- Prevent Inheritance (sealed class + private constructor)
1. Static Class / Utility Class
public static class MathUtils {
// Static class ไม่ต้องการ Constructor — Compiler กันการ Instantiate ให้
public static double PI = 3.14159;
public static int Add(int a, int b) => a + b;
}
หรือ Non-static Class ที่มีเฉพาะ Static Members:
public class Constants {
private Constants() { } // Private Constructor — ป้องกัน new Constants()
public static readonly string AppName = "MyApp";
public static readonly int Version = 1;
}
2. Singleton Pattern
รับประกันว่ามี Instance เพียง 1 ตัวตลอด Lifetime ของ Application
รุ่นคลาสสิก (Thread-Safe ด้วย Lock)
public sealed class Singleton {
private static Singleton _instance;
private static readonly object _lock = new object();
private Singleton() { } // Private Constructor
public static Singleton Instance {
get {
if (_instance == null) {
lock (_lock) {
if (_instance == null) {
_instance = new Singleton();
}
}
}
return _instance;
}
}
public void DoSomething() => Console.WriteLine("Singleton working!");
}
รุ่นสมัยใหม่ (Lazy<T> — Thread-Safe โดยอัตโนมัติ)
public sealed class Singleton {
private static readonly Lazy _instance =
new Lazy(() => new Singleton());
private Singleton() { }
public static Singleton Instance => _instance.Value;
public void DoSomething() => Console.WriteLine("Singleton working!");
}
รุ่น .NET 6+ (Thread-Safe, Lazy, Minimal)
public sealed class Singleton {
private Singleton() { }
public static Singleton Instance { get; } = new Singleton();
public void DoSomething() => Console.WriteLine("Singleton working!");
}
Static Constructor ใน C# รับประกัน Thread-Safety และ Lazy Initialization อัตโนมัติ
การใช้งาน
Singleton.Instance.DoSomething();
// หรือ
var s = Singleton.Instance;
⚠️ ข้อควรพิจารณา
- Singleton เป็น Anti-pattern ในบางบริบท — ทำให้ Unit Testing ยาก, Hidden Dependencies, Global State
- พิจารณา Dependency Injection แทน (Register as Singleton ใน DI Container)
- ถ้าต้องใช้ Singleton ให้ใช้ Lazy<T> หรือ Static Constructor รุ่นใหม่
สรุป
| Pattern | ใช้เมื่อ |
|---|---|
| Private Constructor + Static Class | Utility/Constants เท่านั้น |
| Singleton (Lazy<T>) | ต้องการ Instance เดียว Global Access |
| Factory Method | ควบคุมการสร้าง Instance (Validation, Pooling, Subclass Selection) |
| Dependency Injection | ส่วนใหญ่ — Testable, Loose Coupling, Managed Lifetime |