Static Class** vs **Non-Static (Instance) Class** — ความแตกต่างพื้นฐานใน Design และ Usage
Comparison Table
| Feature | Static Class | Non-Static Class |
|---|---|---|
| Instantiation | ❌ Cannot new | ✅ new MyClass() |
| Members | Static Only (Fields, Methods, Properties, Events) | Instance + Static Members |
| Inheritance | ❌ Sealed Implicitly (Cannot Inherit) | ✅ Can Inherit (Unless Sealed) |
| Constructor | Static Constructor Only (static ClassName()) | Instance + Static Constructors |
| Access Members | ClassName.Member | instance.Member or ClassName.StaticMember |
| Interface Implementation | ❌ Cannot | ✅ Can |
| this Keyword | ❌ Not Available | ✅ Available |
| Extension Methods | ✅ Must Be in Static Class | ❌ Cannot |
Static Class Example
public static class MathUtils {
// Static Constructor (Runs Once, Before First Access)
static MathUtils() {
Console.WriteLine("MathUtils Initialized");
}
public const double PI = 3.14159265359;
public static int Add(int a, int b) => a + b;
public static double CircleArea(double radius) => PI * radius * radius;
// Private Static Field for State
private static int _callCount = 0;
public static int CallCount => _callCount++;
}
// Usage
MathUtils.Add(5, 3); // 8
MathUtils.CircleArea(2.0); // 12.56...
// var m = new MathUtils(); // ❌ Compile Error
Non-Static Class Example
public class Calculator {
// Instance Field
private int _lastResult;
// Instance Method
public int Add(int a, int b) {
_lastResult = a + b;
return _lastResult;
}
// Static Method (Utility)
public static int StaticAdd(int a, int b) => a + b;
// Instance Property
public int LastResult => _lastResult;
}
// Usage
var calc = new Calculator();
calc.Add(5, 3); // Instance Method
Calculator.StaticAdd(1,2); // Static Method
Static Constructor
static class Config {
public static string ConnectionString { get; private set; }
static Config() {
// Runs Once, Thread-Safe, Before First Static Access
ConnectionString = LoadFromConfigFile();
}
private static string LoadFromConfigFile() => "Server=...";
}
เมื่อไหร่ใช้ Static Class?
- Utility/Helper Methods (Math, String Extensions, Conversion)
- Global State / Singleton-like (แต่ DI ดีกว่า)
- Extension Methods Container
- Constants Grouping
เมื่อไหร่ใช้ Non-Static Class?
- ต้องการ State ต่อ Instance (Instance Fields)
- ต้องการ Polymorphism / Inheritance
- ต้องการ Implement Interface
- Multiple Instances with Different Data
- Dependency Injection
⚠️ Static Class Pitfalls
- Global State → Hard to Test, Hidden Dependencies
- Thread Safety: Static Fields ต้อง Synchronize เอง
- ไม่สามารถ Mock ได้ง่ายสำหรับ Unit Testing
- Lifetime = AppDomain Lifetime (ไม่สามารถ Dispose ได้)
Modern Alternative: Static Factory + DI
// แทน Static Class
public interface ICalculator {
int Add(int a, int b);
}
public class Calculator : ICalculator {
public int Add(int a, int b) => a + b;
}
// Register as Singleton in DI Container
services.AddSingleton();