TryParse比Parse好
如果注意觀(guān)察除string外的所有基元類(lèi)型,會(huì )發(fā)現它們都有兩個(gè)將字符串轉型為本身的方法:Parse和TryParse。以類(lèi)型double為例,這兩個(gè)方法最簡(jiǎn)單的原型為:
- 1.public static double Parse(string s)
- 2.public static bool TryParse(string s, out double result)
兩者最大的區別是,如果字符串格式不滿(mǎn)足轉換的要求,Parse方法將會(huì )引發(fā)一個(gè)異常;TryParse方法則不會(huì )引發(fā)異常,它會(huì )返回false,同時(shí)將result置為0。
實(shí)際上,早期的FCL中并沒(méi)有提供TryParse方法,那時(shí)只能調用Parse方法,如果轉型失敗,則要將值設定為一個(gè)初始值,同時(shí)必須要捕獲異常,代碼如下所示:
- string str = null;
- double d;
- try
- {
- d = Double.Parse(str);
- }
- catch (Exception ex)
- {
- d = 0;
- }
要注意,引發(fā)異常這個(gè)過(guò)程會(huì )對性能造成損耗(第5章會(huì )詳細解釋這一點(diǎn))。微軟的開(kāi)發(fā)團隊正是注意到這一點(diǎn),所以從.NET 2.0開(kāi)始,FCL中開(kāi)始為基元類(lèi)型提供TryParse方法。我們不妨來(lái)做個(gè)實(shí)驗,代碼如下所示:
- double re;
- long ticks;
- Stopwatch sw = Stopwatch.StartNew();
- for (int i = 1; i < 1000; i++)
- {
- try
- {
- re = double.Parse("123");
- }
- catch
- {
- re = 0;
- }
- }
- sw.Stop();
- ticks = sw.ElapsedTicks;
- Console.WriteLine("double.Parse() 成功,{0} ticks", ticks);
- sw = Stopwatch.StartNew();
- for (int i = 1; i < 1000; i++)
- {
- if (double.TryParse("123", out re) == false)
- {
- re = 0;
- }
- }
- sw.Stop();
- ticks = sw.ElapsedTicks;
- Console.WriteLine("double.TryParse() 成功,{0} ticks", ticks);
- sw = Stopwatch.StartNew();
- for (int i = 1; i < 1000; i++)
- {
- try
- {
- re = double.Parse("aaa");
- }
- catch
- {
- re = 0;
- }
- }
- sw.Stop();
- ticks = sw.ElapsedTicks;
- Console.WriteLine("double.Parse() 失敗,{0} ticks", ticks);
- sw = Stopwatch.StartNew();
- for (int i = 1; i < 1000; i++)
- {
- if (double.TryParse("aaa", out re) == false)
- {
- re = 0;
- }
- }
- sw.Stop();
- ticks = sw.ElapsedTicks;
- Console.WriteLine("double.TryParse() 失敗,{0} ticks", ticks);
以上這段代碼的輸出為:
- double.Parse() 成功,6661 ticks
- double.TryParse() 成功,2886 ticks
- double.Parse() 失敗,2062347 ticks
- double.TryParse() 失敗,3379 ticks
可見(jiàn), Parse和TryParse方法如果執行成功,它們的效率在一個(gè)數量級上,甚至在本示例中(在一個(gè)循環(huán)內),TryParse所帶來(lái)的效率比Parse還要高一些。但若執行失敗,Parse的執行效率相比于TryParse就太低了。
我們將提供TryParse方法的這種行為叫做類(lèi)型提供TryParse模式。TryParse模式為類(lèi)型提供兩個(gè)方法,假設第一個(gè)方法聲明為Do,第二個(gè)方法則聲明為T(mén)ryDo。Do方法在執行過(guò)程中如果發(fā)生錯誤則引發(fā)異常,而TryDo方法會(huì )返回一個(gè)boolean值,方法執行失敗返回false。如果要從TryDo中獲取實(shí)際的返回值,則應該為方法提供out參數。
不過(guò),我們并不建議為所有的類(lèi)型都提供TryParse模式,只有在考慮到Do方法會(huì )帶來(lái)明顯的性能損耗時(shí),才建議使用TryParse。
聯(lián)系客服