Ketika membandingkan dua string dalam c # untuk kesetaraan, apa perbedaan antara InvariantCulture dan perbandingan Ordinal?
c#
.net
string-comparison
ordinal
Kapil
sumber
sumber
String1.Equals(String2, StringComparison.Ordinal)
, Anda lebih baik menggunakanString1 == String2
yang secara intrinsikString1.Equals(String2)
dan itu secara default perbandingan peka huruf besar-kecil.==
"lebih baik", tetapi itu adalah a) lebih pendek, b) kurang eksplisit tentang apa tepatnya yang dilakukannya dan c)String1
dapat menjadi nol tanpa perbandingan melempar aNullReferenceException
.StringComparison
jenisnya. Dalam kasus perbandingan string, artinyaString.Equals
.NullReferenceException
Anda hanya dapat menggunakan metode statis:String.Equals(string1, string2, StringComparison.Ordinal)
.Jawaban:
Budaya Invariant
Menggunakan seperangkat urutan karakter "standar" (a, b, c, ... dll). Ini berbeda dengan beberapa lokal tertentu, yang dapat mengurutkan karakter dalam urutan yang berbeda ('a-dengan-akut' mungkin sebelum atau setelah 'a', tergantung pada lokal, dan sebagainya).
Urut
Di sisi lain, terlihat murni pada nilai byte mentah yang mewakili karakter.
Ada contoh yang bagus di http://msdn.microsoft.com/en-us/library/e6883c06.aspx yang menunjukkan hasil dari berbagai nilai StringComparison. Sepanjang jalan, itu menunjukkan (dikutip):
Anda dapat melihat bahwa di mana InvariantCulture menghasilkan (U + 0069, U + 0049, U + 00131), hasil ordinal (U + 0049, U + 0069, U + 00131).
sumber
Itu penting, misalnya - ada hal yang disebut ekspansi karakter
Dengan
InvariantCulture
karakter ß diperluas ke ss.sumber
Ordinal
danInvariantCulture
? Itulah pertanyaan aslinya.ß
harus dicatat bahwaß
setidaknya dalam bahasa Jerman sama dengan double s, Sumber: en.wikipedia.org/wiki/%C3%9Fß
dan secarass
bergantian dalam bahasa Jerman (saya seorang penutur asli). Ada kasus-kasus di mana keduanya legal (tetapi seringkali salah satu sudah usang / tidak direkomendasikan) dan ada kasus di mana hanya satu formulir yang diizinkan.Menunjuk ke Praktik Terbaik untuk Menggunakan String di .NET Framework :
StringComparison.Ordinal
atauStringComparison.OrdinalIgnoreCase
untuk perbandingan sebagai standar aman Anda untuk pencocokan string agnostik kultur.StringComparison.Ordinal
atauStringComparison.OrdinalIgnoreCase
untuk kinerja yang lebih baik.StringComparison.Ordinal
atauStringComparison.OrdinalIgnoreCase
bukannya operasi string yang didasarkan padaCultureInfo.InvariantCulture
ketika perbandingan tidak relevan secara linguistik (simbolis, misalnya).Dan akhirnya:
StringComparison.InvariantCulture
kebanyakan kasus . Salah satu dari sedikit pengecualian adalah ketika Anda mempertahankan data agnostik yang secara linguistik bermakna tetapi secara budaya.sumber
Perbedaan praktis lainnya (dalam bahasa Inggris di mana aksen tidak umum) adalah bahwa perbandingan InvariantCulture membandingkan seluruh string dengan case-insensitive pertama, dan kemudian jika perlu (dan diminta) membedakan dengan case setelah terlebih dahulu membandingkan hanya pada huruf yang berbeda. (Anda juga dapat melakukan perbandingan case-insensitive, tentu saja, yang tidak akan membedakan dengan case.) Dikoreksi:Huruf beraksen dianggap sebagai citarasa lain dari huruf-huruf yang sama dan string dibandingkan pertama kali mengabaikan aksen dan kemudian memperhitungkannya jika huruf-huruf umum semuanya cocok (seperti halnya case yang berbeda kecuali pada akhirnya tidak diabaikan dalam perbandingan case-insensitive). Grup-grup ini mengaksen versi-versi kata yang sebaliknya dekat satu sama lain, bukannya sepenuhnya terpisah pada perbedaan aksen pertama. Ini adalah urutan yang biasanya Anda temukan dalam kamus, dengan kata-kata berhuruf besar muncul tepat di sebelah padanan huruf kecilnya, dan huruf beraksen berada di dekat huruf yang tidak beraksen.
Perbandingan ordinal membandingkan secara ketat pada nilai karakter numerik, berhenti pada perbedaan pertama. Jenis huruf besar ini benar-benar terpisah dari huruf kecil (dan huruf beraksen agaknya terpisah dari huruf kecil), jadi kata-kata dengan huruf besar tidak akan menyamai tempat yang dekat dengan huruf kecilnya.
InvariantCulture juga menganggap huruf kapital lebih besar daripada huruf kecil, sedangkan Ordinal menganggap huruf kapital lebih kecil dari huruf kecil (peninggalan ASCII dari masa lalu sebelum komputer memiliki huruf kecil, huruf besar dialokasikan terlebih dahulu dan dengan demikian memiliki nilai lebih rendah dari huruf kecil ditambahkan nanti).
Misalnya, menurut Ordinal:
"0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"
Dan oleh InvariantCulture:
"0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"
sumber
Meskipun pertanyaannya adalah tentang kesetaraan , untuk referensi visual cepat, di sini urutan beberapa string diurutkan menggunakan beberapa budaya yang menggambarkan beberapa keanehan di luar sana.
Pengamatan:
de-DE
,,ja-JP
danen-US
urutkan dengan cara yang samaInvariant
hanya macamss
danß
berbeda dari tiga budaya di atasda-DK
agak berbedaIgnoreCase
hal bendera untuk semua budaya sampelKode yang digunakan untuk menghasilkan tabel di atas:
sumber
CultureComparer
yang dapat kita gunakan untuk memverifikasi. Untuk tabel ini,Danish
budaya (info) ternyata sangat penting.)Invarian adalah jenis perbandingan yang sesuai secara linguistik.
Ordinal adalah jenis perbandingan biner. (lebih cepat)
Lihat http://www.siao2.com/2004/12/29/344136.aspx
sumber
Berikut adalah contoh di mana perbandingan kesetaraan string menggunakan InvariantCultureIgnoreCase dan OrdinalIgnoreCase tidak akan memberikan hasil yang sama:
Jika Anda menjalankan ini, equals1 akan salah, dan equals2 akan benar.
sumber
a="\x00e9"
(e akut) danb="\x0065\x0301"
(e dikombinasikan dengan aksen akut),StringComparer.Ordinal.Equals(a, b)
akan mengembalikan false sementaraStringComparer.InvariantCulture.Equals(a, b)
akan mengembalikan true.Tidak perlu menggunakan exmaples unicode char yang mewah untuk menunjukkan perbedaannya. Inilah satu contoh sederhana yang saya temukan hari ini yang mengejutkan, hanya terdiri dari karakter ASCII.
Menurut tabel ASCII,
0
(0x48) lebih kecil dari_
(0x95) bila dibandingkan secara ordinal. InvariantCulture akan mengatakan sebaliknya (kode PowerShell di bawah):sumber
Selalu mencoba menggunakan InvariantCulture dalam metode string yang menerimanya sebagai kelebihan beban. Dengan menggunakan InvariantCulture Anda berada di sisi yang aman. Banyak pemrogram .NET mungkin tidak menggunakan fungsi ini tetapi jika perangkat lunak Anda akan digunakan oleh budaya yang berbeda, InvariantCulture adalah fitur yang sangat berguna.
sumber