The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

在 .NET 中撰寫 String.Contains 方法時容易犯的錯誤

.NET Framework 中的 String.Contains 方法從 .NET 2.0 時就開始出現,但你可能從未想過這個問題,這個簡單的 String.Contains 方法到底有什麼該注意的地方呢。先考各位一段簡單的程式碼,並先仔細想想如果以下程式碼執行完後,變數 b 的值應該是 True 或 False 呢?

string s1 = "The quick brown fox jumps over the lazy dog";
string s2 = "";
bool b;
b = s1.Contains(s2);

不蠻各位,連我在寫類似這段程式時,大多從心裡直覺的認為答案是 False,直到上週才發現一個幾個月前完成的專案竟然開始出現一些不合理的結果,原本不應該出現的資料全部都出現了。

我會想說,s1 有一堆字串,而 s2 卻是空字串,當判斷 s1 是否包含「空字串」時,怎麼可能會是 True 呢?

我也好奇的問了多位有在寫 .NET 的朋友,不少都是 .NET 撰寫多年且實力不差的開發人員,大家都一致��回答 False

我都說成這樣了,還有人認為答案是 False 嗎?除了我親自跑程式驗證過答案是 True 外,也轉貼 MSDN 上關於 String.Contains 方法的說明,如下圖示:

.NET Framework 類別庫 - String.Contains 方法

這樣的結果著實讓我匪夷所思,像這種簡單到爆的方法(Method)誰會真的認真到仔細的看這種 Method 的 MSDN 文件,而這種違反直覺判斷的程式行為實在是需要「經驗」,遇到了才知道,即便是如此簡單的字串用法。

※ 2009-06-26 補充說明

我多列出幾個跟 String 類別有關的字串比對 Method,供各位參考:

Console.WriteLine("123".Contains(""));    // True
Console.WriteLine("123".StartsWith(""));  // True
Console.WriteLine("123".EndsWith(""));    // True
Console.WriteLine("123".IndexOf(""));     // 0
Console.WriteLine("123".LastIndexOf("")); // 2

總之「空字串」代表的不是「字串」,而擁有一個特殊的意義,你可以想像著每一個字串開頭結尾都會包括一個「空字串」,這個「空字串」本身不佔空間,但卻存在這樣一個虛擬字元,緊緊黏在第一個字元最後一個字元上。

我不知道這樣說明會不會對某些人來說太複雜,但我自己是這樣想像的,可以幫助我記憶這個現象,這樣想以後寫程式的時候就比較不會出錯了。

相關連結