Yang umumnya terbaik untuk digunakan - StringComparison.OrdinalIgnoreCase atau StringComparison.InvariantCultureIgnoreCase?

162

Saya punya beberapa kode seperti ini:

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

Saya tidak peduli dengan kasus ini. Apakah saya harus menggunakan OrdinalIgnoreCase, InvariantCultureIgnoreCaseatau CurrentCultureIgnoreCase?

Dave Haynes
sumber
2
Periksa ini sangat berguna untuk utas ini. Saran saya untuk menggunakan ordianlignorecase untuk perbandingan. blogs.msdn.com/b/noahc/archive/2007/06/29/...
UmaMaheswaran
Pertimbangkan jawaban yang sangat banyak dipilih dari perbandingan String
Michael Freidgeim
Secara keseluruhan, itu sangat tergantung pada hal apa yang Anda bandingkan. Khususnya, jika itu bergantung pada input pengguna atau hal-hal internal. Anda tidak ingin budaya PC mengacaukan perbandingan kode internal.
Nyerguds

Jawaban:

180

Dokumen .Net yang lebih baru sekarang memiliki tabel untuk membantu Anda memutuskan mana yang terbaik untuk digunakan dalam situasi Anda.

Dari " Rekomendasi Baru MSDN untuk Menggunakan String di Microsoft .NET 2.0 "

Rangkuman: Pemilik kode yang sebelumnya menggunakan InvariantCultureperbandingan string, casing, dan penyortiran harus sangat mempertimbangkan untuk menggunakan set Stringkelebihan baru di Microsoft .NET 2.0 Secara khusus, data yang dirancang untuk menjadi agnostik budaya dan tidak relevan secara bahasa harus mulai menentukan kelebihan beban menggunakan salah satu StringComparison.Ordinalatau StringComparison.OrdinalIgnoreCaseanggota StringComparisonenumerasi baru . Ini menegakkan perbandingan byte-by-byte mirip dengan strcmpyang tidak hanya menghindari bug dari interpretasi linguistik pada dasarnya string simbolis, tetapi memberikan kinerja yang lebih baik.

Robert Taylor
sumber
126
Untuk memberikan contoh di mana mereka berbeda, pertimbangkan dua string "Straße"dan "STRASSE". Bila menggunakan OrdinalIgnoreCaseyang Equalskembali false, sedangkan InvariantCultureIgnoreCasemengatakan mereka sama.
Jeppe Stig Nielsen
2
Tautan yang diperbarui: docs.microsoft.com/en-us/dotnet/standard/base-types/…
Ohad Schneider
64

Semuanya tergantung

Membandingkan string unicode sulit:

Implementasi pencarian string Unicode dan perbandingan dalam perangkat lunak pemrosesan teks harus memperhitungkan keberadaan poin kode yang setara. Dengan tidak adanya fitur ini, pengguna yang mencari urutan titik kode tertentu tidak akan dapat menemukan mesin terbang lain yang secara visual tidak dapat dibedakan yang memiliki representasi titik kode yang berbeda, tetapi secara kanonik, berbeda.

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


Jika Anda mencoba membandingkan 2 string unicode dengan case case insensitive dan ingin itu bekerja di MANA SAJA , Anda memiliki masalah yang mustahil.

Contoh klasiknya adalah bahasa Turki i , yang ketika huruf besar menjadi İ (perhatikan titik)

Secara default, framework .Net biasanya menggunakan CurrentCulture untuk fungsi terkait string, dengan pengecualian yang sangat penting .Equalsyang menggunakan perbandingan ordinal (byte by byte).

Ini mengarah, dengan desain, ke berbagai fungsi string berperilaku berbeda tergantung pada budaya komputer.


Meskipun demikian, kadang-kadang kita menginginkan "tujuan umum", case-sensitive, perbandingan.

Misalnya, Anda mungkin ingin perbandingan string Anda berperilaku dengan cara yang sama, apa pun komputer tempat aplikasi Anda diinstal.

Untuk mencapai ini kami memiliki 3 opsi:

  1. Tetapkan budaya secara eksplisit dan lakukan perbandingan kasus yang tidak sensitif menggunakan aturan kesetaraan unicode.
  2. Atur budaya ke Budaya Invariant dan lakukan perbandingan kasus dengan menggunakan aturan kesetaraan unicode.
  3. Gunakan OrdinalIgnoreCase yang akan memperbesar string menggunakan InvariantCulture dan kemudian melakukan perbandingan byte demi byte.

Aturan kesetaraan Unicode rumit, yang berarti menggunakan metode 1) atau 2) lebih mahal daripada OrdinalIgnoreCase. Fakta yang OrdinalIgnoreCasetidak melakukan normalisasi unicode khusus, berarti bahwa beberapa string yang merender dengan cara yang sama di layar komputer, tidak akan dianggap identik. Misalnya: "\u0061\u030a"dan "\u00e5"keduanya membuat å. Namun dalam perbandingan ordinal akan dianggap berbeda.

Yang Anda pilih sangat tergantung pada aplikasi yang Anda buat.

  • Jika saya sedang menulis aplikasi lini bisnis yang hanya digunakan oleh pengguna Turki, saya pasti akan menggunakan metode 1.
  • Jika saya hanya perlu membandingkan kasus sederhana "palsu" tidak sensitif, untuk mengatakan nama kolom dalam db, yang biasanya bahasa Inggris saya mungkin akan menggunakan metode 3.

Microsoft memiliki serangkaian rekomendasi mereka dengan pedoman eksplisit. Namun, sangat penting untuk memahami gagasan kesetaraan unicode sebelum mendekati masalah ini.

Juga, harap diingat bahwa OrdinalIgnoreCase adalah jenis binatang yang sangat istimewa , yaitu mengambil dan memilih sedikit ordinal dibandingkan dengan beberapa campuran dalam aspek leksikografis. Ini bisa membingungkan.

Sam Saffron
sumber
Bagaimana jika saya membangun aplikasi Turki yang hanya akan digunakan oleh pengguna Turki tapi saya ingin "ayakkabı" dan "ayakkabi" sama, apakah ada cara? Ketika orang mengetik di ponsel mereka, kebanyakan dari mereka menggunakan keyboard bahasa Inggris sebagai default dan tidak peduli jika mereka mengetik "ı" atau "i".
Volkan Sen
4

Saya kira itu tergantung pada situasi Anda. Karena perbandingan ordinal sebenarnya melihat nilai Unicode numerik karakter, mereka tidak akan menjadi pilihan terbaik saat Anda mengurutkan berdasarkan abjad. Untuk perbandingan string, meskipun, ordinal akan sedikit lebih cepat.

Menggertak
sumber
1

Itu tergantung pada apa yang Anda inginkan, meskipun saya akan menghindar dari kultur invariant kecuali Anda sangat yakin Anda tidak akan pernah ingin melokalisasi kode untuk bahasa lain. Gunakan CurrentCulture sebagai gantinya.

Juga, OrdinalIgnoreCase harus menghormati angka, yang mungkin atau mungkin tidak seperti yang Anda inginkan.

Joel Coehoorn
sumber
1
Pernah menulis kode VB6 dalam lingkungan bahasa campuran? Anda dapat membuat kode yang mengkompilasi pada PC dengan lokal Prancis tetapi tidak akan mengkompilasi pada PC dengan lokal bahasa Inggris, karena angka apa pun yang disimpan dalam sumber daya formulir menggunakan format lokal saat ini. Saya berpendapat Anda perlu mengambil pendekatan yang berlawanan: berhati-hatilah ketika Anda menggunakan budaya saat ini. Selalu pikirkan apakah sistem Anda akan tetap berfungsi saat datanya berpindah antar budaya. Hal yang sama dengan zona waktu.
Wim Coenen
Saya setuju dengan jawaban "itu tergantung". meskipun tidak mengikuti bit "angka penghormatan"?
Sam Saffron
-1

Jawaban yang sangat sederhana adalah, kecuali Anda menggunakan bahasa Turki, Anda tidak perlu menggunakan InvariantCulture.

Lihat tautan berikut:

Dalam C # apa perbedaan antara ToUpper () dan ToUpperInvariant ()?

TheMoot
sumber
5
Jawaban ini mungkin sederhana, tetapi juga sangat salah. Bahasa Turki "Aku" hanyalah sebuah contoh , ada banyak lagi kemungkinan jebakan.
Ohad Schneider
Yang lebih banyak jebakan? Saya hanya tahu tentang kasus masalah Turki.
HelloWorld
Ya, selain bahasa Turki ada Azeri. Tapi begitulah.
Jim Balter