2009-12-12 19 views
6

我試圖處理到下面的字符:⨝(http://www.fileformat.info/info/unicode/char/2a1d/index.htmstring.Empty.StartsWith(((char)10781).ToString())總是返回true?

如果您檢查一個空字符串是否以該字符開頭,它總是返回true,這並沒有任何意義!這是爲什麼?

// 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())); 

回答

11

您可以通過使用ordinal StringComparison修復這個bug:

從MSDN文檔:

當您指定 StringComparison.Ordinal或 StringComparison.OrdinalIgnoreCase, 字符串比較會 非-linguistic。也就是說,在制定 比較決策時,將忽略特定於自然 語言的功能 。這意味着 的決定基於簡單字節 比較,並忽略套管或 等效表,這些表是通過文化參數化的 。其結果是, 由參數明確設置爲 無論是StringComparison.Ordinal或 StringComparison.OrdinalIgnoreCase, 代碼屢屢斬獲速度,增加 正確性,並變得更加 可靠。

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

文化敏感 - 默認比較看起來像是一個巨大的災難性的違反最小驚喜原則的違反。有沒有什麼經驗法則可以確定哪些方法需要StringComparison來獲得「正常」序數行爲,哪些方法不需要? – bobince 2009-12-12 14:25:23

+0

@ bobince-你見過這個問題 - http:// stackoverflow。COM /問題/ 72696 /這 - 是 - 通常,最好使用的-stringcomparison-ordinalignorecase或 - stringcom – RichardOD 2009-12-12 15:12:54

4

尼斯unicode的毛刺;-p

我不知道爲什麼這樣做,但可笑:

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 

我猜這被視爲有點像非加入字符Jon mentioned at devdays;一些字符串函數看到它,有些則不。如果它沒有看到它,這會變成「確實(某些字符串)以空字符串開頭」,這總是爲真。

+0

+1 from me。我沒有看到喬恩的談話。 – RichardOD 2009-12-13 11:48:57

4

的根本原因是默認的字符串比較是語言環境意識。這意味着使用區域數據表進行比較(包括相等)。

很多(如果不是大多數的話)Unicode字符對許多locale都沒有價值,因此不存在(或者是,但是匹配任何東西,或者什麼都不)。

在邁克爾卡普蘭的博客「Sorting It All Out」上查看有關人物權重的條目。博客的This series包含大量的背景信息(這些API是本地的,但我知道—在.NET中的機制是相同的)。

快速版本:這是得到預期的一個複雜的領域(正常的語言)比較合適的是硬的,這往往會導致奇怪的事情代碼點你的語言之外的字形。