100165375.htm
来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 231 行 · 第 1/4 页
HTM
231 行
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">try</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // code for normal execution</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">catch </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // error handling</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">finally</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // clean up</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">实际上,上面的代码还有几种变体:</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">可以省略</span><span lang="EN-US">finally</span><span style="FONT-FAMILY: 宋体">块</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">可以提供任意多个</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块,处理不同类型的错误。</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">可以省略</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块<span style="LETTER-SPACING: -1pt">——</span></span><span style="LETTER-SPACING: -1pt"> </span><span style="FONT-FAMILY: 宋体">此时,语法应不是标识异常,而是一种确保程序流在离开</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块后执行</span><span lang="EN-US">finally</span><span style="FONT-FAMILY: 宋体">块中的代码的方式,如果在</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块中有几个出口,这是很有用的。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这看起来很不错,实际上是有问题的。如果执行</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块中的代码,则程序流如何在错误发生时切换到</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块上?如果检测到一个错误,代码就执行一定的操作,称为“抛出一个异常”;换言之,它实例化一个异常对象,并抛出这个异常:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">throw new OverflowException();</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这里实例化了</span><span lang="EN-US">OverflowException</span><span style="FONT-FAMILY: 宋体">类的一个异常对象。只要计算机在</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块中遇到一个</span><span lang="EN-US">throw</span><span style="FONT-FAMILY: 宋体">语句,就会立即查找与这个</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块对应的</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块。如果有多个与</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块对应的</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块,计算机就会检查与</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块对应的异常类,确定正确的</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块。例如,当抛出一个</span><span lang="EN-US">OverflowException</span><span style="FONT-FAMILY: 宋体">对象时,执行流就会跳转到下面的</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块上:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><a ftel="throw1"><span lang="EN-US">catch (OverflowException e)</span></a></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">换言之,计算机查找的</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块应表示同一个类</span><span lang="EN-US">(</span><span style="FONT-FAMILY: 宋体">或基类</span><span lang="EN-US">)</span><span style="FONT-FAMILY: 宋体">中匹配的异常类实例。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">有了这些额外的信息,就可以扩展刚才介绍的</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块。为了讨论方便,假定可能在</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块中发生两个严重错误:溢出和数组超出范围。假定代码包含两个布尔变量</span><span lang="EN-US">Overflow</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">OutOfBounds</span><span style="FONT-FAMILY: 宋体">,表示这两种错误情况是否存在。我们知道存在表示溢出的预定义溢出类</span><span lang="EN-US">OverflowException</span><span style="FONT-FAMILY: 宋体">,同样,存在预定义的</span><span lang="EN-US">IndexOutOfRangeException</span><span style="FONT-FAMILY: 宋体">类,用于处理数组超出范围错误。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">现在,</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块如下所示:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">try </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // code for normal execution</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (Overflow == true)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> throw new OverflowException();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // more processing</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (OutOfBounds == true)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> throw new IndexOutOfRangeException();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // otherwise continue normal execution</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">catch (OverflowException e)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // error handling for the overflow error condition</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">catch (IndexOutOfRangeException e)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // error handling for the index out of range error condition</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">finally</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // clean up</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">我们得到的</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块看起来并不比</span><span lang="EN-US">VB6</span><span style="FONT-FAMILY: 宋体">的</span><span lang="EN-US">On Error GoTo</span><span style="FONT-FAMILY: 宋体">语句强多少,但可以更清晰地将不同的代码段分开。实际上,这里的错误处理有一个更强大、更灵活的机制。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这是因为</span><span lang="EN-US">throw</span><span style="FONT-FAMILY: 宋体">语句可以嵌套在</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块的几个方法调用中,甚至在程序流进入其他方法中时,也会继续执行同一个</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块。如果计算机遇到一个</span><span lang="EN-US">throw</span><span style="FONT-FAMILY: 宋体">语句,就会立即退出堆栈中所有的方法调用,查找</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块的结尾和合适的</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 宋体">块的开头,此时,中间方法调用中的所有局部变量都会出作用域。</span><span lang="EN-US">try<sup>…</sup>catch</span><span style="FONT-FAMILY: 宋体">结构最适合于本节开头描述的场合:错误发生在一个方法调用中,而该方法调用可能嵌套了</span><span lang="EN-US">15</span><span style="FONT-FAMILY: 宋体">到</span><span lang="EN-US">20</span><span style="FONT-FAMILY: 宋体">级调用,这些处理操作会立即停止。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">从上面的论述可以看出,</span><span lang="EN-US">try</span><span style="FONT-FAMILY: 宋体">块在控制程序的执行流上有着重要的作用。但是,异常类是用于处理异常情况的,这是其名称的由来。不应该用异常来控制退出</span><span lang="EN-US">do…while</span><span style="FONT-FAMILY: 宋体">循环的时间。</span></p>
<h4 style="FTEL: 21.45pt"><a ftel="_Toc507815039"><span lang="EN-US">1. </span></a><span style="FONT-FAMILY: 黑体">执行多个</span><span lang="EN-US">catch</span><span style="FONT-FAMILY: 黑体">块</span></h4>
<p class="MsoNormal"><a ftel="SimpleExceptions"><span style="FONT-FAMILY: 宋体">了解</span><span lang="EN-US">try<sup>…</sup>catch<sup>…</sup>finally</span></a><span style="FONT-FAMILY: 宋体">块是如何工作的,最简单的方式是用两个示例来说明。第一个示例是</span><span lang="EN-US">SimpleExceptions</span><span style="FONT-FAMILY: 宋体">。它多次要求用户键入一个数字,然后显示这个数字。为了便于解释这个示例,假定该数字必须在</span><span lang="EN-US">0</span><span style="FONT-FAMILY: 宋体">和</span><span lang="EN-US">5</span><span style="FONT-FAMILY: 宋体">之间,否则程序就不能对该数字进行正确的处理。所以,如果用户键入超出该范围的数字,程序就抛出一个异常。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">程序会继续要求用户输入数字,直到用户不再输入任何内容,但按下了回车键为止。</span></p>
<p class="a3" style="MARGIN-TOP: 8.15pt; FTEL: 21.45pt"><span style="FONT-FAMILY: 黑体">注意:</span></p>
<p class="a1" style="FTEL: 21.45pt"><span style="FONT-FAMILY: 楷体_GB2312">这段代码没有提供异常处理。前面已经提及,异常是用于处理异常情况的。用户总是键入一些无聊的东西,所以这种情况不会真正发生。正常情况下,程序会处理不正确的用户输入,进行即时检查,如果有问题,就要求用户重新键入。但是,在一个要求几分钟内读懂的小示例中生成异常是比较困难的,为了描述异常是如何工作的,使用下面这样的示例。</span></p>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?