Menu
CoddyTech

Từ khóa 'readonly' và 'const'

Thuộc phần Lập trình hướng đối tượng trong hành trình C# của Coddy. Bài học 16 trên 70.

C# cung cấp hai từ khóa để tạo các giá trị không thể thay đổi: const và readonly. Cả hai đều ngăn việc sửa đổi, nhưng hoạt động khác nhau và phục vụ những mục đích riêng.

Trường const phải được gán giá trị khi khai báo và giá trị của nó được xác định tại thời điểm biên dịch. Trường này mặc định là tĩnh, nghĩa là nó thuộc về lớp chứ không thuộc về các đối tượng:

public class GameSettings
{
    public const int MaxPlayers = 4;
    public const double Gravity = 9.81;
}

Bạn truy cập các hằng số (constant) thông qua tên lớp: GameSettings.MaxPlayers. Hằng số chỉ hoạt động với các kiểu nguyên thủy, chuỗi và null vì trình biên dịch cần biết giá trị chính xác.

Một trường readonly có thể được gán giá trị khi khai báo hoặc trong hàm khởi tạo, và giá trị của nó được xác định khi chạy:

public class Player
{
    public readonly string Id;
    public readonly DateTime CreatedAt = DateTime.Now;
    
    public Player(string id)
    {
        Id = id;
    }
}

Không giống const, các trường readonly có thể chứa mọi kiểu dữ liệu và có giá trị khác nhau ở mỗi instance. Khi hàm khởi tạo (constructor) chạy xong, giá trị không thể thay đổi.

Dùng const cho các giá trị thực sự phổ quát và không bao giờ thay đổi, chẳng hạn như các hằng số (constant) toán học. Dùng readonly cho các giá trị chỉ nên được thiết lập một lần nhưng có thể khác nhau giữa các đối tượng (object) hoặc cần được tính toán khi chương trình chạy.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống cấu hình mô phỏng vật lý để minh họa khi nào nên dùng const cho các hằng số phổ quát và khi nào nên dùng readonly cho các giá trị chỉ được thiết lập một lần khi chạy chương trình.

Bạn sẽ tạo hai tệp để sắp xếp code:

  • PhysicsConstants.cs: Định nghĩa lớp PhysicsConstants trong không gian tên Simulation. Lớp này nên chứa các hằng số phổ quát không bao giờ thay đổi và có cùng giá trị ở mọi nơi:
    • Một trường const Gravity được đặt thành 9.81
    • Một trường const SpeedOfLight được đặt thành 299792458
    • Một chuỗi const GravityUnit được đặt thành "m/s^2"
  • Projectile.cs: Định nghĩa lớp Projectile trong không gian tên Simulation. Mỗi vật thể được phóng có các giá trị cần được thiết lập một lần khi tạo và không bao giờ thay đổi sau đó:
    • Một trường readonly Name (chuỗi)
    • Một trường readonly InitialVelocity (số thực)
    • Một trường readonly LaunchAngle (số thực, tính bằng độ)
    • Một hàm khởi tạo nhận và thiết lập cả ba giá trị
    • Một phương thức GetMaxHeight() tính độ cao tối đa bằng công thức: (velocity^2 * sin^2(angle)) / (2 * gravity). Dùng Math.Sin() và đổi độ sang radian bằng cách nhân với Math.PI / 180
  • Program.cs: Trong tệp chính, hãy tạo một vật thể được phóng bằng các giá trị đầu vào và hiển thị các hằng số vật lý cùng với độ cao tối đa đã tính của vật thể.

Bạn sẽ nhận ba giá trị đầu vào:

  • Tên vật thể được phóng
  • Vận tốc ban đầu (tính bằng m/s)
  • Góc phóng (tính bằng độ)

In đầu ra theo định dạng sau:

Gravity: {Gravity} {GravityUnit}
Speed of Light: {SpeedOfLight} m/s
Projectile: {Name}
Initial Velocity: {InitialVelocity} m/s
Launch Angle: {LaunchAngle} degrees
Max Height: {maxHeight} m

Làm tròn độ cao tối đa đến 2 chữ số thập phân bằng Math.Round(value, 2).

Ví dụ, nếu các giá trị đầu vào là Rocket, 50 và 45, đầu ra sẽ là:

Gravity: 9.81 m/s^2
Speed of Light: 299792458 m/s
Projectile: Rocket
Initial Velocity: 50 m/s
Launch Angle: 45 degrees
Max Height: 63.71 m

Tự làm thử

using System;
using Simulation;

class Program
{
    public static void Main(string[] args)
    {
        // Đọc các giá trị đầu vào
        string name = Console.ReadLine();
        double velocity = Convert.ToDouble(Console.ReadLine());
        double angle = Convert.ToDouble(Console.ReadLine());

        // TODO: Tạo đối tượng Projectile bằng các giá trị đầu vào

        // TODO: In ra các hằng số vật lý (Gravity kèm đơn vị, Speed of Light)

        // TODO: In ra thông tin của vật thể bay (Name, Initial Velocity, Launch Angle)

        // TODO: Tính và in ra độ cao tối đa (làm tròn đến 2 chữ số thập phân)
    }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch C# online