侯文成的博客

励志成为最优秀的系统架构师

建议4: TryParse比Parse好

建议4: TryParse比Parse好

如果注意观察除string外的所有基元类型,会发现它们都有两个将字符串转型为本身的方法:Parse和TryParse。以类型double为例,这两个方法最简单的原型为:

  1. 1.public static double Parse(string s)  
  2. 2.public static bool TryParse(string s, out double result) 

两者最大的区别是,如果字符串格式不满足转换的要求,Parse方法将会引发一个异常;TryParse方法则不会引发异常,它会返回false,同时将result置为0。

实际上,早期的FCL中并没有提供TryParse方法,那时只能调用Parse方法,如果转型失败,则要将值设定为一个初始值,同时必须要捕获异常,代码如下所示:

  1. string str = null;  
  2. double d;  
  3. try  
  4. {  
  5.     d = Double.Parse(str);  
  6. }  
  7. catch (Exception ex)  
  8. {  
  9.     d = 0;  

要注意,引发异常这个过程会对性能造成损耗(第5章会详细解释这一点)。微软的开发团队正是注意到这一点,所以从.NET 2.0开始,FCL中开始为基元类型提供TryParse方法。我们不妨来做个实验,代码如下所示:

  1. double re;  
  2. long ticks;  
  3.  
  4. Stopwatch sw = Stopwatch.StartNew();  
  5. for (int i = 1; i < 1000; i++)  
  6. {  
  7.     try  
  8.     {  
  9.         re = double.Parse("123");  
  10.     }  
  11.     catch  
  12.     {  
  13.         re = 0;  
  14.     }  
  15. }  
  16. sw.Stop();  
  17. ticks = sw.ElapsedTicks;  
  18. Console.WriteLine("double.Parse() 成功,{0} ticks", ticks);  
  19.  
  20. sw = Stopwatch.StartNew();  
  21. for (int i = 1; i < 1000; i++)  
  22. {  
  23.     if (double.TryParse("123", out re) == false)  
  24.     {  
  25.         re = 0;  
  26.     }  
  27. }  
  28. sw.Stop();  
  29. ticks = sw.ElapsedTicks;  
  30. Console.WriteLine("double.TryParse() 成功,{0} ticks", ticks);  
  31.  
  32. sw = Stopwatch.StartNew();  
  33. for (int i = 1; i < 1000; i++)  
  34. {  
  35.     try  
  36.     {  
  37.         re = double.Parse("aaa");  
  38.     }  
  39.     catch  
  40.     {  
  41.         re = 0;  
  42.     }  
  43. }  
  44. sw.Stop();  
  45. ticks = sw.ElapsedTicks;  
  46. Console.WriteLine("double.Parse() 失败,{0} ticks", ticks);  
  47.  
  48. sw = Stopwatch.StartNew();  
  49. for (int i = 1; i < 1000; i++)  
  50. {  
  51.     if (double.TryParse("aaa", out re) == false)  
  52.     {  
  53.         re = 0;  
  54.     }  
  55. }  
  56. sw.Stop();  
  57. ticks = sw.ElapsedTicks;  
  58. Console.WriteLine("double.TryParse() 失败,{0} ticks", ticks); 

以上这段代码的输出为:

  1. double.Parse() 成功,6661 ticks  
  2. double.TryParse() 成功,2886 ticks  
  3. double.Parse() 失败,2062347 ticks  
  4. double.TryParse() 失败,3379 ticks 

可见, Parse和TryParse方法如果执行成功,它们的效率在一个数量级上,甚至在本示例中(在一个循环内),TryParse所带来的效率比Parse还要高一些。但若执行失败,Parse的执行效率相比于TryParse就太低了。

我们将提供TryParse方法的这种行为叫做类型提供TryParse模式。TryParse模式为类型提供两个方法,假设第一个方法声明为Do,第二个方法则声明为TryDo。Do方法在执行过程中如果发生错误则引发异常,而TryDo方法会返回一个boolean值,方法执行失败返回false。如果要从TryDo中获取实际的返回值,则应该为方法提供out参数。

不过,我们并不建议为所有的类型都提供TryParse模式,只有在考虑到Do方法会带来明显的性能损耗时,才建议使用TryParse。

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

阅读更多
文章标签: TryParse Parse
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

建议4: TryParse比Parse好

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭