本文由中国C#技术学习中心整理 如果你对本文有不明之处请到技术论坛讨论!
第七章 异常处理
通用语言运行时(CLR)具有的一个很大的优势为,异常处理是跨语言被标准化的.一个在C#中所引发的异常可以在Visual Basic客户中得到处理.不再有 HRESULTs 或者 ISupportErrorInfo 接口?gt;」芸缬镅砸斐4淼母哺敲婧芄?但这一章完全集中讨论C#异常处理.你稍为改变编译器的溢出处理行为,接着有趣的事情就开始了:你处理了该异常.要增加更多的手段,随后引发你所创建的异常.
7.1 校验( checked )和非校验( unchecked )语句
当你执行运算时,有可能会发生计算结果超出结果变量数据类型的有效范围.这种情况被称为溢出,依据不同的编程语言,你将被以某种方式通知——或者根本就没有被通知.(C++程序员听起来熟悉吗?)
那么,C#如何处理溢出的呢? 要找出其默认行为,请看我在这本书前面提到的阶乘的例子.(为了方便其见,前面的例子再次在清单 7.1 中给出)
清单 7.1 计算一个数的阶乘
1: using System; 2: 3: class Factorial 4: { 5: public static void Main( string[] args ) 6: { 7: long nFactorial = 1; 8: long nComputeTo = Int64.Parse( args[0] ); 9: 10: long nCurDig = 1; 11: for ( nCurDig=1; nCurDig <= nComputeTo; nCurDig++ ) 12: nFactorial *= nCurDig; 13: 14: Console.WriteLine( "{0}! is {1}",nComputeTo, nFactorial ); 15: } 16: }
当你象这样使用命令行执行程序时
factorial 2000
结果为0,什么也没有发生.因此,设想C#默默地处理溢出情况而不明确地警告你是安全的. 通过给整个应用程序(经编译器开关)或于语句级允许溢出校验,你就可以改变这种行为.以下两节分别解决一种方案.
7.1.1 给溢出校验设置编译器
如果你想给整个应用程序控制溢出校验,C#编译器设置选择是正是你所要找的.默认地,溢出校验是禁用的.要明确地要求它,运行以下编译器命令:
csc factorial.cs /checked+
现在当你用2000参数执行应用程序时,CLR通知你溢出异常.
按OK键离开对话框揭示了异常信息:
Exception occurred: System.OverflowException at Factorial.Main( System.String[] )
现在你了解了溢出条件引发了一个 System.OverflowException异常.下一节,在我们完成语法校验之后,如何捕获并处理所出现的异常?
7.1.2 语法溢出校验
如果你不想给整个应用程序允许溢出校验,仅给某些代码段允许校验,你可能会很舒适.对于这种场合,你可能象清单7.2中显示的那样,使用校验语句.
清单 7.2 阶乘计算中的溢出校验
1: using System; 2: 3: class Factorial 4: { 5: public static void Main( string[] args ) 6: { 7: long nFactorial = 1; 8: long nComputeTo = Int64.Parse( args[0] ); 9: 10: long nCurDig = 1; 11: 12: for ( nCurDig=1; nCurDig <= nComputeTo; nCurDig++ ) 13: checked { nFactorial *= nCurDig; } 14: 15: Console.WriteLine( "{0}! is {1}",nComputeTo, nFactorial ); 16: } 17: }
甚至就如你运用标志 checked-编译了该代码,在第13行中,溢出校验仍然会对乘法实现检查.错误信息保持一致.
显示相反行为的语句是非校验(unchecked ).甚至如果允许了溢出校验(给编译器加上checked+标志),被unchecked 语句所括住的代码也将不会引发溢出异常:
unchecked { nFactorial *= nCurDig; }
本文由中国C#技术学习中心整理 如果你对本文有不明之处请到技术论坛讨论!
|