2009-12-12 34 views
6

aşağıdaki karaktere işlemek için çalışıyor: ⨝ (http://www.fileformat.info/info/unicode/char/2a1d/index.htm)string.Empty.StartsWith (((char) 10781) .ToString()) her zaman doğru döner?

boş bir dize bu karakterle başlayan olmadığını kontrol, bu her zaman true döndürür, bu hiç mantıklı değil! Neden?

// visual studio 2008 hides lines that have this char literally (bug in visual studio?!?) so i wrote it's unicode instead. 
char specialChar = (char)10781; 
string specialString = specialChar.ToString(); 

// prints 1 
Console.WriteLine(specialString.Length); 

// prints 10781 
Console.WriteLine((int)specialChar); 

// prints false 
Console.WriteLine(string.Empty.StartsWith("A")); 

// both prints true WTF?!? 
Console.WriteLine(string.Empty.StartsWith(specialString)); 
Console.WriteLine(string.Empty.StartsWith(((char)10781).ToString())); 

cevap

11

Sen ordinal StringComparison kullanarak bu hatayı düzeltebilirsiniz: MSDN Dokümanlar

: string karşılaştırma olmayan olacak

ya StringComparison.Ordinal veya StringComparison.OrdinalIgnoreCase, belirtirken -linguistic. Yani, diline özgü özellikleri, karşılaştırma kararları verirken göz ardı edilir. Bu, kararlarının, basit byte karşılaştırmaları temel aldığını ve kültür tarafından parametrelenmiş eşdeğer muhafazasını veya eşdeğerlik tablolarını temel aldığını gösterir. Açıkça StringComparison.Ordinal ya da StringComparison.OrdinalIgnoreCase parametresini ayarlayarak sonucunda, gibi, kodunuzu genellikle hız kazanır doğruluğunu artırır ve güvenilir fazla olur.

char specialChar = (char)10781; 


    string specialString = Convert.ToString(specialChar); 

    // prints 1 
    Console.WriteLine(specialString.Length); 

    // prints 10781 
    Console.WriteLine((int)specialChar); 

    // prints false 
    Console.WriteLine(string.Empty.StartsWith("A")); 

    // prints false 
    Console.WriteLine(string.Empty.StartsWith(specialString, StringComparison.Ordinal)); 
+0

Kültür duyarlı-karşılaştırma-varsayılan olarak, en az sürpriz ilkesi büyük bir felaket ihlali gibi görünüyor. Normal "ordinal davranışlar elde etmek için hangi yöntemlerin StringComparison gerektirdiğini belirlemek için hangi kurallar var?" – bobince

+0

@ bobince- bu soruyu gördünüz mü? Http: // stackoverflow.com/sorular/72696 /-is-genel-iyi kullanımlı-stringcomparison-ordinalignorecase-ya-stringcom – RichardOD

4

amusingly Güzel unicode

Ben bunu neden yaptığını emin değilim ;-p aksaklık ama:

Console.WriteLine(string.Empty.StartsWith(specialString)); // true 
Console.WriteLine(string.Empty.Contains(specialString)); // false 
Console.WriteLine("abc".StartsWith(specialString)); // true 
Console.WriteLine("abc".Contains(specialString)); // false 

bu olmayan gibi biraz tedavi edilir tahmin ediyorum Jon mentioned at devdays; Bazı dize fonksiyonları görüyor, bazıları yapmıyor. Ve eğer görmüyorsa, bu "boş bir dizeyle başlıyor (bazı dizgiler" haline gelir) ", her zaman true.

+0

+1 benden. Jon'un konuşmasını görmemiştim. – RichardOD

4

Bunun altında yatan nedeni varsayılan dize karşılaştırması yerel farkında olmasıdır. Bu, karşılaştırmalar için (eşitlik dahil) yerel veri tablolarının kullanılması anlamına gelir.

Çoğu (çoğu değilse) Unicode karakterleri birçok yerel için bir değere sahip değildir ve bu nedenle yoktur (veya yapar, ancak bir şeyle eşleşmez, veya hiçbir şey).

Michael Kaplan'ın "Sorting It All Out" adlı blogundaki karakter ağırlıkları hakkındaki girişleri görün. Blogların This series bir çok arka plan bilgisi içerir (API'ler yereldir, ancak — anladığım kadarıyla — .NET'teki mekanizmalar aynıdır).

Hızlı versiyon: Bu, beklenen (normal dil) karşılaştırmaların doğru olması için karmaşık bir alandır; bu, dilinizin dışındaki glifler için kod noktaları ile garip şeylere yol açma eğilimindedir.