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.
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ớpPhysicsConstantstrong không gian tênSimulation. 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
constGravityđược đặt thành9.81 - Một trường
constSpeedOfLightđược đặt thành299792458 - Một chuỗi
constGravityUnitđược đặt thành"m/s^2"
- Một trường
Projectile.cs: Định nghĩa lớpProjectiletrong không gian tênSimulation. 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
readonlyName(chuỗi) - Một trường
readonlyInitialVelocity(số thực) - Một trường
readonlyLaunchAngle(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ùngMath.Sin()và đổi độ sang radian bằng cách nhân vớiMath.PI / 180
- Một trường
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} mLà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 mTự 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)
}
}
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
1Các khái niệm cơ bản về lập trình hướng đối tượng
Tệp bên ngoàiKhông gian tên và chỉ thịGiới thiệu về lớp và đối tượngTừ khóa thisPhương thức và tham sốTrường và thuộc tínhHàm khởi tạoKhởi tạo đối tượngÔn tập: Máy tính đơn giản4Kế thừa
Cú pháp kế thừa cơ bản (:)Từ khóa 'base'Từ khóa virtual và overrideLớp sealedLớp cơ sở 'object'Ôn tập: hệ phân cấp nhân viên7Tính năng nâng cao
Nạp chồng toán tửBộ lập chỉ mục (this[])Ghi đè ToString()Phương thức mở rộngÔn tập: Danh sách tùy chỉnh10Các mẫu thiết kế phần 1
Giới thiệu về mẫu thiết kếSingleton an toàn với luồngMẫu FactoryMẫu Observer (sự kiện)Mẫu Strategy2Thuộc tính và thành viên tĩnh
Thuộc tính tự độngThuộc tính chỉ đọc hoặc chỉ ghiTrường và phương thức tĩnhLớp tĩnhThành viên có thân biểu thức5Đa hình và interface
Đa hình lúc biên dịch và lúc chạyInterface và lớp trừu tượngNhiều interfaceInterface tường minhUpcasting và downcastingÔn tập: bộ tính toán hình học8Các khái niệm OOP nâng cao
Ưu tiên composition hơn kế thừaGenerics (lớp và phương thức)Delegate và sự kiệnAttribute và reflectionGiao diện IDisposable và câu lệnh usingKiến thức cơ bản về dependency injection11Các mẫu thiết kế phần 2
Mẫu lệnhMẫu bộ chuyển đổiMẫu trang tríMẫu phương thức khuôn mẫuMẫu trạng tháiMẫu tổ hợp3Kiến trúc lớp
Dữ liệu instance và dữ liệu tĩnhTừ khóa 'readonly' và 'const'Trường lưu trữÔn tập: Trình quản lý tài khoản ngân hàngTự luyện tập: Trình biên dịch C# online