คำสำคัญ static ใน C# ใช้กำหนดให้สมาชิกของคลาส (ตัวแปร, เมธอด, Property, Constructor) เป็นของ คลาสเอง ไม่ใช่ของอินสแตนซ์ (Instance) หมายความว่า ไม่ว่าจะสร้างออบเจ็กต์จากคลาสกี่ตัว จะมีเพียง หนึ่งคอปปี้ ของสมาชิก static นั้นเท่านั้น
คุณสมบัติของ Static Members
- เข้าถึงผ่าน ชื่อคลาส โดยไม่ต้องสร้างออบเจ็กต์:
ClassName.StaticMember - มีอยู่เพียงหนึ่งคอปปี้ในหน่วยความจำ (Shared across all instances)
- เหมาะสำหรับ: Constants, Counters, Utility Methods, Singleton Pattern
- Static method เรียกใช้ static member อื่นๆ ได้โดยตรง แต่ ไม่สามารถเรียก instance member ได้
ตัวอย่าง Static Variable
using System;
namespace StaticVarApplication {
class StaticVar {
public static int num; // Static field - แชร์ร่วมกันทุก instance
public void Count() {
num++; // เพิ่มค่าร่วมกัน
}
public static int GetNum() { // Static method
return num;
}
}
class StaticTester {
static void Main(string[] args) {
StaticVar s1 = new StaticVar();
StaticVar s2 = new StaticVar();
s1.Count();
s1.Count();
s1.Count(); // num = 3
s2.Count();
s2.Count();
s2.Count(); // num = 6 (แชร์ค่าเดียวกัน!)
Console.WriteLine("Variable num for s1: {0}", s1.GetNum()); // 6
Console.WriteLine("Variable num for s2: {0}", s2.GetNum()); // 6
// เรียกผ่านชื่อคลาสได้โดยตรง
Console.WriteLine("Via class name: {0}", StaticVar.GetNum()); // 6
Console.ReadKey();
}
}
}
ผลลัพธ์
Variable num for s1: 6
Variable num for s2: 6
Static Constructor
รันเพียงครั้งเดียว ก่อนที่จะสร้าง instance แรก หรือเข้าถึง static member แรก ใช้สำหรับ initialization แบบ complex
class Database {
static string connectionString;
// Static constructor - ไม่มี access modifier, ไม่มีพารามิเตอร์
static Database() {
connectionString = LoadFromConfig();
Console.WriteLine("Static constructor called");
}
static string LoadFromConfig() => "Server=...;Database=...;";
}
Static Class
คลาสที่มี เฉพาะ static members เท่านั้น ไม่สามารถสร้าง instance ได้ (sealed โดยอัตโนมัติ)
public static class MathUtils {
public const double PI = 3.14159;
public static double CircleArea(double radius) {
return PI * radius * radius;
}
}
// ใช้งาน
double area = MathUtils.CircleArea(5); // 78.53975
Static vs Instance - สรุปความแตกต่าง
| คุณสมบัติ | Static Member | Instance Member |
|---|---|---|
| การเข้าถึง | ClassName.Member | instance.Member |
| หน่วยความจำ | 1 คอปปี้ต่อ AppDomain | 1 คอปปี้ต่อ Object |
| เข้าถึง this | ไม่ได้ | ได้ |
| เรียก Instance Member | ไม่ได้โดยตรง | ได้ |
| Override/Polymorphism | ไม่ได้ | ได้ (virtual/override) |
Best Practices
- ใช้ static สำหรับ Pure Functions (ไม่มี side effect, ผลลัพธ์ขึ้นอยู่กับ input เท่านั้น)
- หลีกเลี่ยง static state (mutable static fields) ในระบบ Multi-threaded - อาจเกิด Race Condition
- ใช้
readonlyกับ static fields ที่เป็นค่าคงที่ - พิจารณา Dependency Injection แทน Static Classes เพื่อ Testability