Genellikle hangisi kullanılır - StringComparison.OrdinalIgnoreCase veya StringComparison.InvariantCultureIgnoreCase?


162

Ben böyle bir kod var:

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

Davayı umursamıyorum. Ben kullanmalı mıyım OrdinalIgnoreCase, InvariantCultureIgnoreCaseya CurrentCultureIgnoreCase?


2
Bu iş parçacığı için gerçekten yararlı olduğunu kontrol edin. Karşılaştırma için ordianlignorecase kullanma önerim. blogs.msdn.com/b/noahc/archive/2007/06/29/…
UmaMaheswaran


Genel olarak, ne tür bir şey karşılaştırdığınıza çok bağlıdır. Özellikle, kültüre bağımlı kullanıcı girdisi veya dahili öğeler ise. PC kültürünün dahili kod dizesini karşılaştırmasını istemezsiniz.
Nyerguds

Yanıtlar:


180

Daha yeni .Net Docs uygulamasında artık hangisinin durumunuzda en iyi şekilde kullanılacağına karar vermenize yardımcı olacak bir tablo var.

MSDN'den " Microsoft .NET 2.0'da Dizeleri Kullanmak için Yeni Öneriler "

Özet: Daha önce InvariantCulturedize karşılaştırma, kasa ve sıralama için kullanılan kod sahipleri String, Microsoft .NET 2.0'da yeni bir aşırı yükler kümesi kullanmayı düşünmelidir . Spesifik olarak, kültüre karşı agnostik ve dilsel olarak alakasız olacak şekilde tasarlanan veriler , yeni numaralandırmanın ya StringComparison.Ordinalda StringComparison.OrdinalIgnoreCaseüyelerini kullanarak aşırı yükleri belirlemeye başlamalıdır StringComparison. Bunlar, benzer bir bayt-byte karşılaştırmasını strcmpzorunlu kılar, sadece hataların temel olarak sembolik dizelerin dilsel yorumundan kaçınmakla kalmaz, aynı zamanda daha iyi performans sağlar.


126
Farklı oldukları yerde bir örnek vermek için, iki dizeyi "Straße"ve "STRASSE". Kullanırken döner , oysa onlar eşit olduğunu söylüyor. OrdinalIgnoreCaseEqualsfalseInvariantCultureIgnoreCase
Jeppe Stig Nielsen


64

Hepsi bağlıdır

Unicode dizelerini karşılaştırmak zordur:

Metin işleme yazılımında Unicode string aramalarının ve karşılaştırmalarının uygulanması, eşdeğer kod noktalarının varlığını dikkate almalıdır. Bu özelliğin yokluğunda, belirli bir kod noktası dizisini arayan kullanıcılar, farklı ancak kanonik olarak eşdeğer bir kod noktası gösterimine sahip, görsel olarak ayırt edilemeyen diğer glifleri bulamazlar.

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


2 unicode dizeyi büyük / küçük harfe duyarlı olmayan bir şekilde karşılaştırmaya çalışıyorsanız ve HER YERDE çalışmasını istiyorsanız, imkansız bir sorununuz var demektir.

Klasik örnek Türkçe i , üst harfli olduğunda İ olur (noktayı fark eder)

Varsayılan olarak, .Net çerçevesi sıralı (bayt bayt) karşılaştırma kullanan çok önemli bir istisna dışında, dize ile ilgili işlevler için CurrentCulture'u.Equals kullanır.

Bu, tasarım gereği, bilgisayarın kültürüne bağlı olarak farklı davranan çeşitli dize işlevlerine yol açar.


Bununla birlikte, bazen "genel amaçlı", büyük / küçük harfe duyarlı olmayan bir karşılaştırma istiyoruz.

Örneğin, uygulamanızın yüklü olduğu bilgisayar ne olursa olsun dize karşılaştırmanızın aynı şekilde davranmasını isteyebilirsiniz.

Bunu başarmak için 3 seçeneğimiz var:

  1. Kültürü açıkça ayarlayın ve unicode denklik kurallarını kullanarak büyük / küçük harfe duyarlı olmayan bir karşılaştırma yapın.
  2. Invariant Kültür kültürü ayarlayın ve unicode denklik kurallarını kullanarak büyük / küçük harf duyarsız karşılaştırma gerçekleştirmek.
  3. InvariantCulture kullanarak dizeyi büyük harf olacak OrdinalIgnoreCase kullanın ve sonra bir bayt bayt karşılaştırma gerçekleştirin.

Unicode denklik kuralları karmaşıktır, yani yöntem 1) veya 2) 'nin kullanılması daha pahalıdır OrdinalIgnoreCase. Aslında OrdinalIgnoreCaseherhangi bir özel unicode normalleşmesini, bir bilgisayar ekranında aynı şekilde işlemek bazı dizeleri, araçlara gerçekleştirmez olmaz özdeş kabul. Örneğin: "\u0061\u030a"ve "\u00e5"her ikisi de å. Ancak sıralı karşılaştırmada farklı kabul edilecektir.

Hangisini çok fazla tercih edeceğiniz, yaptığınız uygulamaya bağlıdır.

  • Yalnızca Türk kullanıcılar tarafından kullanılan bir iş kolu uygulaması yazsaydım, yöntem 1'i kullandığınızdan emin olurdum.
  • Ben sadece basit bir "sahte" büyük / küçük harf duyarsız karşılaştırmak gerekirse, db bir sütun adı için genellikle İngilizce olan ben muhtemelen yöntem 3 kullanacağım.

Microsoft, açık yönergelerle kendi önerilerine sahiptir. Bununla birlikte, bu sorunlara yaklaşmadan önce unicode denklik kavramını anlamak gerçekten önemlidir.

Ayrıca, OrdinalIgnoreCase'in çok özel bir canavar türü olduğunu unutmayın , bu da bazı sözlükbilimsel yönlerde karışık olanlarla karşılaştırmak ve biraz sıralı bir seçim yapmaktır . Bu kafa karıştırıcı olabilir.


Yalnızca Türk kullanıcılar tarafından kullanılacak bir Türkçe uygulama oluşturuyorsam ama "ayakkabı" ve "ayakkabi" nin eşit olmasını istiyorsam, bir yolu var mı? Kullanıcılar telefonlarına yazdıklarında, çoğu İngilizce klavyeyi varsayılan olarak kullanır ve "ı" veya "i" yazıp yazmadıklarını umursamazlar.
Volkan Şen

4

Sanırım durumunuza bağlı. Sıralı karşılaştırmalar aslında karakterlerin sayısal Unicode değerlerine baktığından, alfabetik olarak sıralarken en iyi seçim olmayacaktır. Bununla birlikte, dize karşılaştırmaları için sıra sıra biraz daha hızlı olurdu.


1

Ne istediğinize bağlı, ancak çok değişmedikçe değişmez kültürden çekindim emin diğer diller için kod yerelleştirilmesine istemeyeceksiniz. Bunun yerine CurrentCulture kullanın.

Ayrıca, OrdinalIgnoreCase, istediğiniz gibi olabilecek veya olmayabilecek sayılara saygı göstermelidir.


1
Hiç karma bir ortamda VB6 kodu yazdınız mı? Form kaynaklarında depolanan sayılar geçerli yerel ayarın biçimini kullandığından, Fransızca yerel ayarlı bir bilgisayarda derlenen ancak İngilizce yerel ayarlı bilgisayarlarda derlenmeyecek kodlar oluşturabilirsiniz. Ben zıt yaklaşımı benimsemen gerektiğini savunuyorum: mevcut kültürü kullanırken çok dikkatli ol. Verileri kültürler arasında hareket ettiğinde daima sisteminizin hala çalışıp çalışmayacağını düşünün. Zaman dilimleri ile aynı şey.
Wim Coenen

"Bu duruma bağlı" yanıtı kabul ediyorum. Peki "sayılar saygı" bit takip değil?
Sam Saffron

-1

Çok basit cevap, Türkçe kullanmadığınız sürece InvariantCulture kullanmanıza gerek yok.

Aşağıdaki bağlantıya bakın:

C # 'da ToUpper () ve ToUpperInvariant () arasındaki fark nedir?


5
Bu cevap basit olabilir, ama aynı zamanda çok yanlıştır. Türk "Ben" sadece bir örnek , daha birçok olası tuzak var.
Ohad Schneider

Hangi tuzak daha var? Ben sadece türk sorununu biliyorum.
HelloWorld

Evet, Türkçe'ye ek olarak Azeri var. Ama bu kadar.
Jim Balter
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.