<<展现C#>> 第七章 异常处理(修订)

     第七章   异常处理

 

    通用语言运行时(CLR)具有的一个很大的优势为异常处理是跨语言被标准化的。一个在C#中所引发的异常可以在Visual Basic客户中得到处理。不再有 HRESULTs  或者 ISupportErrorInfo 接口。

    尽管跨语言异常处理的覆盖面很广,但这一章完全集中讨论C#异常处理。你稍为改变编译器的溢出处理行为,接着有趣的事情就开始了:你处理了该异常。要增加更多的手段,随后引发你所创建的异常。

 

7.1  检查和非检查语句(checked and unchecked statements)

    当你执行运算时,有可能会发生计算结果超出结果变量数据类型的有效范围。这种情况被称为溢出,依据不同的编程语言,你将被以某种方式通知——或者根本就没有被通知。(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通知你溢出异常(见图 7.1)。

 

7.1 允许了溢出异常,阶乘代码产生了一个异常。

 

 

 

  按确定键离开对话框出现了异常信息:

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行中,溢出检查仍然会对乘法实施检查,因为checked 语句已经括住了它。将会出现相同的错误信息。

  显示相反行为的语句是unchecked 。甚至如果允许了溢出检查(给编译器加上checked+标志),被unchecked 语句所括住的代码也将不会引发溢出异常:

 

unchecked

{

 nFactorial *= nCurDig;

}

 

7.2  异常处理语句

  既然你知道了如何产生一个异常(你会发现更多的方法,相信我),仍然存在如何处理它的问题。如果你是一个 C++ WIN32 程序员,肯定熟悉SEH(结构异常处理)。令人感到欣慰的是,C#中的命令几乎是相同的,而且它们也以相似的方式运作。

 

以下三节介绍了C#的异常处理语句:

。用 try-catch 捕获异常

。用try-finally 清除异常

。用try-catch-finally 处理所有的异常

 

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rainbow

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值