CodeGym /Các khóa học /C# SELF /Câu lệnh switch cổ điển

Câu lệnh switch cổ điển

C# SELF
Mức độ , Bài học
Có sẵn

1. Giới thiệu

Hãy tưởng tượng bạn là barista ở một quán cà phê nổi tiếng. Có khách đến và gọi một trong năm món yêu thích. Bạn không ngồi phân tích triết học, mà chỉ cần nhìn menu và phản ứng nhanh: “Cappuccino? Ok luôn! Đây cappuccino của bạn nè!”. Nếu bạn kiểm tra từng món bằng if riêng, code của bạn sẽ như chồng ly sau giờ cao điểm — cồng kềnh và khó chịu lắm.

Câu lệnh switch giúp bạn kiểm tra giá trị biến một cách gọn gàng và thực hiện các hành động khác nhau tùy kết quả. Nó chỉ hoạt động với một số kiểu dữ liệu nhất định (xem bên dưới), nhưng trong hầu hết menu người dùng, lệnh đơn giản hoặc nhận diện trạng thái thì đây là công cụ lý tưởng luôn.

2. Cú pháp switch cổ điển trong C#

Đây là sơ đồ khối tối thiểu:


switch (Biểu_thức) {
    case Giá_trị1:
        // hành động
        break;
    case Giá_trị2:
        // hành động
        break;
    ...
    default:
        // hành động mặc định
        break;
}
Cú pháp switch cổ điển trong C#

Ví dụ 1: menu cổ điển

Console.WriteLine("Chọn đồ uống: 1 - Cà phê, 2 - Trà, 3 - Ca cao");
string input = Console.ReadLine();
int choice = int.Parse(input);

switch (choice)
{
    case 1:
        Console.WriteLine("Bạn đã chọn cà phê. Tuyệt vời!");
        break;
    case 2:
        Console.WriteLine("Trà cũng ngon mà.");
        break;
    case 3:
        Console.WriteLine("Ca cao — dành cho ai thích ấm cúng!");
        break;
    default:
        Console.WriteLine("Menu không có món này.");
        break;
}
  • Khối switch kiểm tra choice có bằng giá trị sau case không.
  • Sau mỗi trường hợp phải có break; — nếu không, chương trình sẽ chạy tiếp sang case tiếp theo (xem bên dưới).
  • Khối default — giống như else; nó chạy nếu không có case nào khớp.

switch hoạt động bên trong như thế nào? — Từng bước

  1. Đầu tiên, tính giá trị biểu thức trong ngoặc sau switch (ở ví dụ là biến choice).
  2. Chương trình so sánh nó với từng giá trị (case) theo thứ tự.
  3. Nếu khớp — thực hiện các lệnh trong block đó. Sau đó gặp break, chương trình thoát khỏi switch.
  4. Nếu không khớp case nào, thực hiện block default (nếu có).

Sơ đồ trực quan

Giá trị biến case 1 case 2 case 3 default
1 +
2 +
3 +
khác +

«+» — block này sẽ được thực hiện

3. Những kiểu dữ liệu nào được switch cổ điển hỗ trợ?

Trong cú pháp cổ điển (tức là, chưa có "Pattern Matching" và các tính năng mới, sẽ nói sau!) switch hỗ trợ:

  • Các kiểu số nguyên đơn giản (int, byte, char, long, short, sbyte, ushort, uint, ulong)
  • Chuỗi (string)
  • Enum (enum)
  • Ký tự (char)

Ví dụ 2: switch với string

Console.WriteLine("Chọn lệnh: start, stop, pause");
string command = Console.ReadLine();

switch (command)
{
    case "start":
        Console.WriteLine("Chương trình đã chạy!");
        break;
    case "stop":
        Console.WriteLine("Chương trình đã dừng.");
        break;
    case "pause":
        Console.WriteLine("Chương trình đang tạm dừng.");
        break;
    default:
        Console.WriteLine("Lệnh không xác định.");
        break;
}

4. Tại sao cần break và nếu quên thì sao?

Lỗi phổ biến nhất của newbie là quên break; trong case. Cùng xem chuyện gì xảy ra nếu bỏ qua nó nhé.

Ví dụ 3: rơi xuống block tiếp theo (fall-through)

int day = 2;

switch (day)
{
    case 1:
        Console.WriteLine("Thứ hai");
        break;
    case 2:
        Console.WriteLine("Thứ ba");
    case 3:
        Console.WriteLine("Thứ tư");
        break;
    default:
        Console.WriteLine("Ngày không xác định");
        break;
}

Chuyện gì sẽ xảy ra?

  • Input là day = 2.
  • Đầu tiên sẽ in: "Thứ ba"
  • Không có break — chương trình chạy tiếp vào case 3 và in: "Thứ tư"
  • Sau đó gặp break; — thoát.

Kết quả trên màn hình:

Thứ ba
Thứ tư

Đây là lỗi điển hình!

  • Nếu bạn chỉ muốn thực hiện MỘT hành động, hãy đặt break; ở mỗi case.
  • Nếu (hiếm) bạn muốn một số trường hợp chạy cùng logic, có thể “gộp” chúng lại (xem bên dưới).

5. Gom nhóm các giá trị case

Đôi khi vài giá trị cần xử lý giống nhau. Sao phải copy code làm gì?

Ví dụ 4: phản ứng giống nhau cho nhiều case

char grade = 'B';

switch (grade)
{
    case 'A':
    case 'B':
    case 'C':
        Console.WriteLine("Qua môn!");
        break;
    case 'D':
    case 'E':
        Console.WriteLine("Còn phải cố gắng.");
        break;
    default:
        Console.WriteLine("Điểm không hợp lệ.");
        break;
}

Chuyện gì xảy ra?

  • Nếu grade'A', 'B' hoặc 'C', block đầu tiên chạy: "Qua môn!".
  • Nếu 'D' hoặc 'E' — block thứ hai.
  • Nếu khác — default.

6. Được và không được trong switch cổ điển

Được:

  • Dùng literal (hằng số) trong case, ví dụ: case 1:, case 'A':, case "dừng":.
  • So sánh enum (liệt kê).
  • Có thể bỏ default, nhưng thường nên có.

Không được:

  • Dùng biến trong case (chỉ dùng hằng số thôi).
  • So sánh theo khoảng (case >= 5:, case x > 10: — không được nhé!).
  • Dùng double, float và các số thực khác — chỉ dùng số nguyên, string, char, enum thôi.
  • Viết nhiều giá trị trong một case bằng dấu phẩy (case 1, 2: không được; hãy viết nhiều case liên tiếp).

7. Đặc điểm và lỗi thường gặp

Trong dự án thực tế, switch hay dùng cho menu, xử lý trạng thái, lệnh, mã lỗi và cả ngàn thứ khác. Nhưng cũng như mọi công cụ, nó có vài lưu ý.

Lỗi thường gặp:

  • Quên break (đã nói ở trên).
  • Sai kiểu dữ liệu trong switch (ví dụ, thử dùng double).
  • Không khớp chữ hoa/thường của string (case "Start": sẽ không khớp với "start") — string so sánh phân biệt hoa thường nhé!
  • Không xử lý giá trị ngoài dự kiến (quên default, người dùng nhập linh tinh).

Bẫy với switch lồng nhau
Dù bạn có thể gặp kiểu code này, nhưng thường nó rất khó đọc. Nếu bạn thấy mình lồng switch trong switch, có lẽ nên tách code ra thành method riêng hoặc dùng OOP/enum/mảng cho gọn.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION