Cái nào thường tốt nhất để sử dụng - StringComparison.OrdinalIgnoreCase hoặc StringComparison.InvariantCARMIgnoreCase?


161

Tôi có một số mã như thế này:

If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
    DoSomething()
End If

Tôi không quan tâm đến vụ án. Tôi có nên sử dụng OrdinalIgnoreCase, InvariantCultureIgnoreCasehoặc CurrentCultureIgnoreCase?


2
Kiểm tra điều này thực sự hữu ích cho chủ đề này. Đề nghị của tôi để sử dụng ordianlignorecase để so sánh. blogs.msdn.com/b/noahc/archive/2007/06/29/...
UmaMaheswaran

Xem xét câu trả lời được bình chọn cao từ so sánh Chuỗi
Michael Freidgeim

Nhìn chung, nó phụ thuộc rất nhiều vào loại điều bạn đang so sánh. Cụ thể, nếu đó là đầu vào của người dùng phụ thuộc vào văn hóa hoặc nội dung. Bạn không muốn văn hóa của PC làm rối tung so sánh chuỗi mã nội bộ.
Nyerguds

Câu trả lời:


179

Tài liệu .Net mới hơn hiện có một bảng để giúp bạn quyết định sử dụng cái nào là tốt nhất trong tình huống của bạn.

Từ " Khuyến nghị mới về sử dụng chuỗi trong Microsoft .NET 2.0 " của MSDN

Tóm tắt: Chủ sở hữu mã trước đây sử dụng InvariantCultureso sánh chuỗi, vỏ và sắp xếp chuỗi nên cân nhắc mạnh mẽ bằng cách sử dụng một bộ Stringquá tải mới trong Microsoft .NET 2.0. Cụ thể, dữ liệu được thiết kế để có văn hóa-agnostic và ngôn ngữ không thích hợp nên bắt đầu xác định quá tải sử dụng một trong hai StringComparison.Ordinalhoặc StringComparison.OrdinalIgnoreCasethành viên của mới StringComparisonliệt kê. Chúng thực thi một phép so sánh theo từng byte tương tự như strcmpđiều đó không chỉ tránh các lỗi từ việc giải thích ngôn ngữ của các chuỗi ký hiệu cơ bản, mà còn cung cấp hiệu suất tốt hơn.


126
Để đưa ra một ví dụ nơi chúng khác nhau, hãy xem xét hai chuỗi "Straße""STRASSE". Khi sử dụng OrdinalIgnoreCasecác Equalslợi nhuận false, trong khi đó InvariantCultureIgnoreCasenói rằng họ đang bằng nhau.
Jeppe Stig Nielsen


63

Tất cả phụ thuộc vào

So sánh các chuỗi unicode là khó:

Việc thực hiện tìm kiếm và so sánh chuỗi Unicode trong phần mềm xử lý văn bản phải tính đến sự hiện diện của các điểm mã tương đương. Nếu không có tính năng này, người dùng đang tìm kiếm một chuỗi điểm mã cụ thể sẽ không thể tìm thấy các glyph không thể phân biệt trực quan khác có biểu diễn điểm mã khác, nhưng tương đương về mặt quy tắc.

xem: http://en.wikipedia.org/wiki/Unicode_equivalence


Nếu bạn đang cố gắng so sánh 2 chuỗi unicode theo cách không phân biệt chữ hoa chữ thường và muốn nó hoạt động MỌI NƠI , bạn có một vấn đề không thể xảy ra.

Ví dụ kinh điển là i Thổ Nhĩ Kỳ , khi chữ hoa trở thành chữ (chú ý dấu chấm)

Theo mặc định, khung .Net thường sử dụng CurrentCARM cho các hàm liên quan đến chuỗi, với một ngoại lệ rất quan trọng .Equalslà sử dụng phép so sánh thứ tự (byte theo byte).

Điều này dẫn, theo thiết kế, đến các hàm chuỗi khác nhau hoạt động khác nhau tùy thuộc vào văn hóa của máy tính.


Tuy nhiên, đôi khi chúng tôi muốn một "mục đích chung", trường hợp không nhạy cảm, so sánh.

Ví dụ, bạn có thể muốn so sánh chuỗi của mình hoạt động theo cùng một cách, bất kể ứng dụng của bạn được cài đặt trên máy tính nào.

Để đạt được điều này, chúng tôi có 3 lựa chọn:

  1. Đặt văn hóa rõ ràng và thực hiện so sánh không phân biệt chữ hoa chữ thường bằng các quy tắc tương đương unicode.
  2. Đặt văn hóa thành Văn hóa bất biến và thực hiện so sánh không phân biệt chữ hoa chữ thường bằng các quy tắc tương đương unicode.
  3. Sử dụng OrdinalIgnoreCase sẽ viết hoa chuỗi bằng cách sử dụng InvariantCARM và sau đó thực hiện so sánh byte theo byte.

Các quy tắc tương đương Unicode rất phức tạp, có nghĩa là sử dụng phương pháp 1) hoặc 2) đắt hơn OrdinalIgnoreCase. Thực tế là OrdinalIgnoreCasekhông thực hiện bất kỳ chuẩn hóa unicode đặc biệt nào, có nghĩa là một số chuỗi kết xuất theo cùng một cách trên màn hình máy tính, sẽ không được coi là giống hệt nhau. Ví dụ: "\u0061\u030a""\u00e5"cả hai kết xuất å. Tuy nhiên trong một so sánh thứ tự sẽ được coi là khác nhau.

Mà bạn chọn rất nhiều phụ thuộc vào ứng dụng bạn đang xây dựng.

  • Nếu tôi đang viết một ứng dụng kinh doanh chỉ dành cho người dùng Thổ Nhĩ Kỳ, tôi chắc chắn sẽ sử dụng phương pháp 1.
  • Nếu tôi chỉ cần một so sánh không nhạy cảm trường hợp "giả" đơn giản, ví dụ như một tên cột trong db, thường là tiếng Anh, tôi có thể sẽ sử dụng phương thức 3.

Microsoft có bộ khuyến nghị của họ với các hướng dẫn rõ ràng. Tuy nhiên, điều thực sự quan trọng là phải hiểu khái niệm tương đương unicode trước khi tiếp cận những vấn đề này.

Ngoài ra, xin lưu ý rằng OrdinalIgnoreCase là một loại quái thú rất đặc biệt , đó là chọn và chọn một chút so sánh thông thường với một số khía cạnh hỗn hợp trong từ vựng. Điều này có thể gây nhầm lẫn.


4

Tôi đoán nó phụ thuộc vào tình hình của bạn. Vì các so sánh thứ tự thực sự đang xem xét các giá trị Unicode số của các ký tự, chúng sẽ không phải là lựa chọn tốt nhất khi bạn sắp xếp theo thứ tự bảng chữ cái. Tuy nhiên, để so sánh chuỗi, thứ tự sẽ nhanh hơn một chút.


1

Nó phụ thuộc vào những gì bạn muốn, mặc dù tôi muốn né tránh InvariantCulture trừ khi bạn đang rất chắc chắn bạn sẽ không bao giờ muốn để bản địa hoá mã cho các ngôn ngữ khác. Sử dụng CurrentCARM thay thế.

Ngoài ra, OrdinalIgnoreCase nên tôn trọng các con số, có thể hoặc không thể là những gì bạn muốn.


1
Bao giờ viết mã VB6 trong môi trường ngôn ngữ hỗn hợp? Bạn có thể tạo mã biên dịch trên PC bằng ngôn ngữ tiếng Pháp nhưng sẽ không biên dịch trên PC với ngôn ngữ tiếng Anh, bởi vì bất kỳ số nào được lưu trữ trong tài nguyên biểu mẫu đều sử dụng định dạng của miền địa phương hiện tại. Tôi cho rằng bạn cần có cách tiếp cận ngược lại: hãy thật cẩn thận khi bạn sử dụng văn hóa hiện tại. Luôn luôn suy nghĩ về việc hệ thống của bạn sẽ vẫn hoạt động khi dữ liệu của nó di chuyển giữa các nền văn hóa. Điều tương tự với múi giờ.
Wim Coenen

Tôi đồng ý với câu trả lời "nó phụ thuộc". mặc dù không theo bit "số tôn trọng"?
Sam Saffron

-1

Câu trả lời rất đơn giản là, trừ khi bạn đang sử dụng tiếng Thổ Nhĩ Kỳ, bạn không cần sử dụng InvariantCARM.

Xem liên kết sau:

Trong C #, sự khác biệt giữa ToUpper () và ToUpperInvariant () là gì?


5
Câu trả lời này có thể đơn giản, nhưng nó cũng rất sai. Chữ "I" của Thổ Nhĩ Kỳ chỉ là một ví dụ , có nhiều cạm bẫy có thể xảy ra hơn.
Ohad Schneider

Cạm bẫy nào hơn? Tôi chỉ biết trường hợp vấn đề Thổ Nhĩ Kỳ.
HelloWorld

Vâng, ngoài tiếng Thổ Nhĩ Kỳ còn có Azeri. Nhưng kia là nó.
Jim Balter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.