TryParse比Parse好
如果注意觀察除string外的所有基元類型,會發(fā)現(xiàn)它們都有兩個將字符串轉型為本身的方法:Parse和TryParse。以類型double為例,這兩個方法最簡單的原型為: - 1.public static double Parse(string s)
- 2.public static bool TryParse(string s, out double result)
兩者最大的區(qū)別是,如果字符串格式不滿足轉換的要求,Parse方法將會引發(fā)一個異常;TryParse方法則不會引發(fā)異常,它會返回false,同時將result置為0。
實際上,早期的FCL中并沒有提供TryParse方法,那時只能調用Parse方法,如果轉型失敗,則要將值設定為一個初始值,同時必須要捕獲異常,代碼如下所示:
- string str = null;
- double d;
- try
- {
- d = Double.Parse(str);
- }
- catch (Exception ex)
- {
- d = 0;
- }
要注意,引發(fā)異常這個過程會對性能造成損耗(第5章會詳細解釋這一點)。微軟的開發(fā)團隊正是注意到這一點,所以從.NET 2.0開始,F(xiàn)CL中開始為基元類型提供TryParse方法。我們不妨來做個實驗,代碼如下所示: - 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
可見, Parse和TryParse方法如果執(zhí)行成功,它們的效率在一個數(shù)量級上,甚至在本示例中(在一個循環(huán)內),TryParse所帶來的效率比Parse還要高一些。但若執(zhí)行失敗,Parse的執(zhí)行效率相比于TryParse就太低了。
我們將提供TryParse方法的這種行為叫做類型提供TryParse模式。TryParse模式為類型提供兩個方法,假設第一個方法聲明為Do,第二個方法則聲明為TryDo。Do方法在執(zhí)行過程中如果發(fā)生錯誤則引發(fā)異常,而TryDo方法會返回一個boolean值,方法執(zhí)行失敗返回false。如果要從TryDo中獲取實際的返回值,則應該為方法提供out參數(shù)。
不過,我們并不建議為所有的類型都提供TryParse模式,只有在考慮到Do方法會帶來明顯的性能損耗時,才建議使用TryParse。
|