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

Final Local Variables ใน C# (readonly)

คำตอบ: ใช้ readonly Keyword

C# ไม่มีคีย์เวิร์ด final เหมือน Java แทนนั้นใช้ readonly สำหรับ Field/Variable ที่ต้องการให้กำหนดค่าได้ครั้งเดียว (ระหว่าง Declaration หรือใน Constructor)

readonly vs const

คุณสมบัติ const readonly
กำหนดค่าเมื่อไหร่ Compile Time (ตอนประกาศ) Runtime (ใน Constructor)
Static โดยค่าเริ่มต้น ใช่ (Implicit Static) ไม่ใช่ (Instance หรือ Static ได้)
Type ที่รองรับ Primitive Types, String, Enum, Null ทุก Type (Reference Types รวม)
การใช้งาน Constant Values (Pi, MaxSize) Runtime Constants, DI, Configuration
Memory แทนค่าตรงโค้ด (Constant Folding) Field จริงใน Object

ตัวอย่าง readonly Field

public class Department {
    // readonly Field - กำหนดค่าได้ครั้งเดียว
    private readonly int _employeeCount;
    
    // Constructor - ที่นี่กำหนดค่า readonly ได้
    public Department(int employeeCount) {
        _employeeCount = employeeCount; // OK
    }
    
    public void ChangeCount() {
        // _employeeCount = 150; // ❌ Compile Error: A readonly field cannot be assigned to
    }
    
    public int GetEmployeeCount() => _employeeCount;
}

readonly กับ Reference Types

สำคัญ: readonly ป้องกันการเปลี่ยน Reference ไม่ใช่การเปลี่ยน Object Content

public class Team {
    // readonly List - Reference ไม่เปลี่ยนได้ แต่ Conent เปลี่ยนได้!
    private readonly List _members = new List();
    
    public void AddMember(string name) {
        _members.Add(name); // ✅ OK - เปลี่ยน Content ของ List
    }
    
    public void ReplaceList() {
        // _members = new List(); // ❌ Error - เปลี่ยน Reference
    }
}

ตัวอย่างครบถ้วน

using System;
using System.Collections.Generic;

public class Employee {
    // Compile-time Constant
    public const string CompanyName = "TechCorp";
    
    // Runtime Constant (readonly)
    private readonly int _id;
    private readonly DateTime _hireDate;
    private readonly List _skills;
    
    // Constructor - กำหนดค่า readonly ทั้งหมด
    public Employee(int id, DateTime hireDate, List skills) {
        _id = id;
        _hireDate = hireDate;
        _skills = skills ?? new List(); // 防御性编程
    }
    
    // Method ที่พยายามเปลี่ยน readonly
    public void TryChangeId(int newId) {
        // _id = newId; // ❌ Compile Error
    }
    
    // Method ที่แก้ไข Content ของ readonly List
    public void AddSkill(string skill) {
        _skills.Add(skill); // ✅ OK
    }
    
    public void Display() {
        Console.WriteLine($"ID: {_id}, Hired: {_hireDate:d}, Skills: {string.Join(", ", _skills)}");
    }
}

class Program {
    static void Main() {
        var emp = new Employee(1001, DateTime.Now, new List { "C#", "SQL" });
        emp.AddSkill("Azure"); // OK - modify content
        emp.Display();
        
        // emp._id = 999; // ❌ Compile Error - readonly
    }
}

Static readonly

public class Config {
    // Static readonly - ค่าเดียวกันทั้ง Application, กำหนดได้ใน Static Constructor
    public static readonly string ConnectionString;
    public static readonly int MaxConnections = 100; // Inline init OK
    
    static Config() {
        // Static Constructor - รันครั้งเดียวก่อนใช้งานครั้งแรก
        ConnectionString = LoadFromConfigFile();
    }
    
    private static string LoadFromConfigFile() {
        return "Server=localhost;Database=MyDB;";
    }
}

สรุป

  • C# ใช้ readonly แทน final
  • readonly = กำหนดค่าได้ 1 ครั้ง (ใน Constructor หรือ Inline)
  • const = Compile-time Constant (Implicit Static)
  • readonly Reference Type = Reference คงที่ แต่ Object Content เปลี่ยนได้
  • ใช้ readonly สำหรับ Dependency Injection, Configuration, Immutable Objects