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

Class Variables และ Static Variables ใน C#

C# มี 2 ประเภทตัวแปรระดับ Class: Static Variables (Static Fields) และ Instance Variables (Instance Fields)

Static Variables (Class Variables)

เป็นของ Type เอง ไม่ใช่ Instance แชร์ค่าให้ทุก Instance


using System;

public class StaticVar
{
    public static int Count = 0; // Static Field

    public StaticVar()
    {
        Count++; // เพิ่มทุกครั้งที่สร้าง Instance
    }

    public static void Reset() => Count = 0;
}

public class Program
{
    public static void Main()
    {
        var s1 = new StaticVar();
        var s2 = new StaticVar();
        var s3 = new StaticVar();

        Console.WriteLine(StaticVar.Count); // 3 - แชร์ค่าเดียวกัน

        StaticVar.Reset();
        Console.WriteLine(StaticVar.Count); // 0
    }
}

Instance Variables (Class Variables / Fields)

เป็นของแต่ละ Instance แยกต่างหาก


public class Box
{
    // Private Fields (Encapsulation)
    private double _length;
    private double _breadth;
    private double _height;

    // Public Properties (Accessors)
    public double Length
    {
        get => _length;
        set => _length = value > 0 ? value : throw new ArgumentException("Length must be positive");
    }

    public double Breadth { get => _breadth; set => _breadth = value; }
    public double Height { get => _height; set => _height = value; }

    // Method
    public double GetVolume() => _length * _breadth * _height;
}

public class Program
{
    public static void Main()
    {
        Box box1 = new Box { Length = 6, Breadth = 7, Height = 5 };
        Box box2 = new Box { Length = 12, Breadth = 13, Height = 10 };

        Console.WriteLine($"Box1 Volume: {box1.GetVolume()}"); // 210
        Console.WriteLine($"Box2 Volume: {box2.GetVolume()}"); // 1560
    }
}

ผลลัพธ์


Box1 Volume: 210
Box2 Volume: 1560

Static vs Instance - ตารางเปรียบเทียบ

ด้านStatic FieldInstance Field
Memory1 ต่อ Type (AppDomain)1 ต่อ Instance
LifetimeProcess DurationInstance Lifetime
AccessClassName.Fieldinstance.Field
Thread Safetyต้อง Lock เองแยก Instance แยกกัน
Inheritanceซ่อน (Hiding) ไม่ OverrideOverride ได้ (ถ้า Virtual)
Serializationมักไม่ SerializeSerialize ปกติ

Static Constructor


public class Config
{
    public static string ConnectionString { get; private set; }
    public static int MaxConnections { get; private set; }

    // Static Constructor - รันครั้งเดียวก่อน First Access
    static Config()
    {
        Console.WriteLine("Static Constructor Running...");
        ConnectionString = LoadFromConfig();
        MaxConnections = 100;
    }

    private static string LoadFromConfig() => "Server=...";
}

Constants vs Static Readonly


public class Constants
{
    // Compile-time Constant - ต้องเป็น Literal, Implicit Static
    public const double PI = 3.14159265359;

    // Runtime Constant - สามารถคำนวณได้, ใช้กับ Object ได้
    public static readonly DateTime AppStartTime = DateTime.Now;

    // Static Readonly with Complex Init
    public static readonly string[] SupportedFormats = 
        Directory.GetFiles("formats", "*.fmt").Select(Path.GetFileName).ToArray();
}

Best Practices

  • Static Fields: ใช้สำหรับ Shared State, Constants, Caches, Counters
  • Instance Fields: ใช้สำหรับ Object State (Data per Object)
  • หลีกเลี่ยง Public Fields → ใช้ Properties
  • Static Mutable State → Thread Safety (Lock, Interlocked, Concurrent Collections)
  • Prefer `static readonly` over `const` สำหรับ Complex Types