Như bạn đã biết, viết thường hai chuỗi và so sánh chúng không giống như thực hiện so sánh chữ hoa và chữ thường. Có rất nhiều lý do cho điều này. Ví dụ, tiêu chuẩn Unicode cho phép văn bản có dấu được mã hóa theo nhiều cách. Một số ký tự bao gồm cả ký tự cơ sở và dấu phụ trong một điểm mã. Các ký tự này cũng có thể được biểu diễn dưới dạng ký tự cơ sở theo sau là ký tự dấu phụ kết hợp. Hai cách đại diện này ngang nhau cho tất cả các mục đích và các so sánh chuỗi nhận biết văn hóa trong .NET Framework sẽ xác định chính xác chúng là bằng nhau, với CurrentCulture hoặc InvariantCulture (có hoặc không có lờ mờ). Mặt khác, so sánh theo thứ tự sẽ không chính xác coi chúng là không bình đẳng.
Thật không may, switch
không làm bất cứ điều gì ngoài một so sánh thứ tự. So sánh thứ tự là tốt cho một số loại ứng dụng, chẳng hạn như phân tích cú pháp tệp ASCII với các mã được xác định chặt chẽ, nhưng so sánh chuỗi thứ tự là sai đối với hầu hết các mục đích sử dụng khác.
Những gì tôi đã làm trong quá khứ để có được hành vi chính xác chỉ là mô phỏng tuyên bố chuyển đổi của chính tôi. Có rất nhiều cách để làm điều này. Một cách sẽ là tạo một List<T>
cặp chuỗi trường hợp và đại biểu. Danh sách có thể được tìm kiếm bằng cách so sánh chuỗi thích hợp. Khi kết quả phù hợp được tìm thấy thì đại biểu được liên kết có thể được gọi.
Một lựa chọn khác là thực hiện chuỗi if
câu lệnh rõ ràng . Điều này thường hóa ra không quá tệ vì cấu trúc này rất đều đặn.
Điều tuyệt vời về điều này là thực sự không có bất kỳ hình phạt hiệu suất nào trong việc chế nhạo chức năng chuyển đổi của riêng bạn khi so sánh với các chuỗi. Hệ thống sẽ không tạo bảng nhảy O (1) theo cách mà nó có thể làm với các số nguyên, vì vậy dù sao thì nó cũng sẽ so sánh từng chuỗi một.
Nếu có nhiều trường hợp cần so sánh và hiệu suất là một vấn đề, thì List<T>
tùy chọn được mô tả ở trên có thể được thay thế bằng từ điển được sắp xếp hoặc bảng băm. Khi đó, hiệu suất có thể khớp hoặc vượt quá tùy chọn câu lệnh chuyển đổi.
Dưới đây là một ví dụ về danh sách các đại biểu:
delegate void CustomSwitchDestination();
List<KeyValuePair<string, CustomSwitchDestination>> customSwitchList;
CustomSwitchDestination defaultSwitchDestination = new CustomSwitchDestination(NoMatchFound);
void CustomSwitch(string value)
{
foreach (var switchOption in customSwitchList)
if (switchOption.Key.Equals(value, StringComparison.InvariantCultureIgnoreCase))
{
switchOption.Value.Invoke();
return;
}
defaultSwitchDestination.Invoke();
}
Tất nhiên, bạn có thể sẽ muốn thêm một số tham số tiêu chuẩn và có thể là kiểu trả về cho đại biểu CustomSwitchDestination. Và bạn sẽ muốn tạo ra những cái tên hay hơn!
Nếu hành vi của mỗi trường hợp của bạn không thể ủy quyền lệnh gọi theo cách này, chẳng hạn như nếu các thông số khác nhau là cần thiết, thì bạn đang mắc kẹt với các trạng thái bị xích if
. Tôi cũng đã làm điều này một vài lần.
if (s.Equals("house", StringComparison.InvariantCultureIgnoreCase))
{
s = "window";
}
else if (s.Equals("business", StringComparison.InvariantCultureIgnoreCase))
{
s = "really big window";
}
else if (s.Equals("school", StringComparison.InvariantCultureIgnoreCase))
{
s = "broken window";
}
ToUpperInvariant()
hoặcToLowerInvariant()
? Ngoài ra, anh ta không so sánh hai chuỗi không xác định , anh ta so sánh một chuỗi không xác định với một chuỗi đã biết. Do đó, miễn là anh ta biết cách mã hóa biểu diễn chữ hoa hoặc chữ thường phù hợp thì khối chuyển đổi sẽ hoạt động tốt.