1. Biểu thức vs Lệnh
Trong C#, tất cả lệnh được chia thành hai loại: lệnh (Statement) và biểu thức (Expression). Về lệnh thì thường nói là nó được thực thi, còn biểu thức thì được tính toán. Nhưng đó không phải là điểm chính.
Điểm khác biệt chính: biểu thức có kết quả tính toán. Kết quả này có kiểu, và bạn có thể gán nó cho biến hoặc dùng trong biểu thức khác.
Ví dụ:
| Mã | Ghi chú |
|---|---|
|
Lệnh |
|
Biểu thức, kiểu bool |
|
Biểu thức, kiểu giống kiểu biến i |
|
Biểu thức, kiểu giống kiểu biến x |
Điều này giúp gì cho ta?
Nhiều lệnh thực ra là biểu thức (có kết quả tính toán). Ví dụ, đoạn code này chạy được:int x, y, z;
x = y = z = 1; // x = (y = (z = 1));
Bạn có thể bỏ qua kết quả của biểu thức nếu không cần:
Console.ReadLine(); // bỏ qua kết quả nhập vào
Rất tiện nếu biểu thức ngoài kết quả còn làm gì đó hữu ích (ví dụ in ra màn hình hoặc đọc input).
2. Toán tử ba ngôi
Trong C# có toán tử ba ngôi (toán tử ba phần) đặc biệt. Nó giống như viết tắt của if–else:
Điều kiện ? Biểu thức1 : Biểu thức2;
Nếu Điều kiện đúng, sẽ tính Biểu thức1, ngược lại — Biểu thức2. Sau điều kiện là ?, hai biểu thức ngăn cách bởi :.
Khác biệt chính với if-else: toán tử ba ngôi là một biểu thức, kết quả của nó có thể gán cho biến hoặc dùng trong biểu thức khác.
Ví dụ, tính giá trị nhỏ nhất của hai số:
int a = 2;
int b = 3;
int min = a < b ? a : b;
Hoặc gán giá trị cho biến tuỳ theo điều kiện:
int age = 25;
int money;
if (age > 30)
money = 100;
else
money = 50;
Làm tương tự với toán tử ba ngôi:
int age = 25;
int money = age > 30 ? 100 : 50;
Nên dùng if-else hay toán tử ba ngôi? Về tốc độ thì như nhau, nhưng toán tử ba ngôi hợp cho điều kiện ngắn. Nếu code dài quá một dòng — nên dùng if-else cho dễ đọc.
3. Những lưu ý khi dùng
Kiểu giá trị
Cả hai nhánh của toán tử ba ngôi (<giá_trị_nếu_đúng> và <giá_trị_nếu_sai>) phải cùng kiểu hoặc tương thích (ví dụ, đều là string hoặc đều là int).
Chạy được:
int a = 10, b = 20;
int max = (a > b) ? a : b; // cả hai nhánh — int
Lỗi biên dịch:
int a = 10, b = 20;
// string và int không tương thích
string result = (a > b) ? "nhiều hơn" : 0; // Lỗi biên dịch
Cách đúng:
int a = 10, b = 20;
string result = (a > b) ? "nhiều hơn" : "ít hơn hoặc bằng";
Ví dụ: làm việc với số
int number = -5;
int abs = (number >= 0) ? number : -number;
Console.WriteLine(abs); // 5
4. Nhúng toán tử ba ngôi vào ứng dụng
Viết thử một app hội thoại: ngoài chào hỏi, chương trình sẽ nói cho người dùng biết năm sau họ bao nhiêu tuổi, và họ có thành người trưởng thành không.
Console.Write("Nhập tên của bạn: ");
string name = Console.ReadLine();
Console.Write("Nhập tuổi của bạn: ");
string ageText = Console.ReadLine();
int age = int.Parse(ageText);
int nextYear = age + 1;
string status = (nextYear >= 18) ? "trưởng thành" : "chưa trưởng thành";
Console.WriteLine($"Chào, {name}! Năm sau bạn sẽ {nextYear} tuổi. Bạn sẽ {status}.");
Giải thích chi tiết:
- Biến status được tính bằng toán tử ba ngôi: nếu tuổi năm sau không nhỏ hơn 18, tức là người dùng sẽ trưởng thành (hoặc vẫn trưởng thành).
- Toán tử ba ngôi có thể nhúng thẳng vào chuỗi (ví dụ với nội suy $"").
5. Toán tử ba ngôi lồng nhau — cẩn thận nhé!
Toán tử ba ngôi có thể lồng nhau (mỗi nhánh lại là một toán tử ba ngôi khác). Nhưng… đọc xong dễ đau đầu lắm, nhất là người đọc code sau bạn (kể cả chính bạn sau 2 ngày).
Ví dụ: xác định nhóm tuổi
string category = (age < 7) ? "mẫu giáo" :
(age < 18) ? "học sinh" :
(age < 65) ? "người lớn" : "người già";
Bảng quyết định:
| Tuổi | Điều kiện | Kết quả |
|---|---|---|
| < 7 | age < 7 | mẫu giáo |
| 7–17 | age < 18 | học sinh |
| 18–64 | age < 65 | người lớn |
| 65 trở lên | ngược lại | người già |
Code này còn đọc được, nhưng nếu logic phức tạp hơn — nên dùng if-else if-else.
6. Mẹo: toán tử ba ngôi và kiểu bool
Đôi khi gặp code như này:
bool adult = (age >= 18) ? true : false;
Nhưng như vậy là thừa. Biểu thức (age >= 18) đã trả về bool rồi. Vậy nên chỉ cần:
bool adult = (age >= 18);
GO TO FULL VERSION