C# 异常处理

在这里,您将学习使用try,catch和finally块在C#中进行异常处理的知识。

必须处理应用程序中的异常,以防止程序崩溃和意外结果,记录异常并继续执行其他功能。C#提供内置支持使用 try,catch和finally块 来处理异常。

语法:

try{//将代码放在这里可能会引发异常}catch{//在这里处理异常}finally{//最终清理代码}

try 块:任何可能引发异常的可疑代码都应放在一个try{ }块中。在执行过程中,如果发生异常,则控制流跳至第一个匹配catch块。

catch :catch块是异常处理程序块,您可以在其中执行一些操作,例如记录和审核异常。catch块采用异常类型的参数,您可以使用该参数获取异常的详细信息。

finally :finally无论是否引发异常,都将始终执行该块。通常,finally应该使用一个块来释放资源,例如,关闭在try块中打开的任何流或文件对象。

如果您输入非数字字符,则以下内容可能会引发异常。

classProgram{staticvoidMain(string[]args){Console.WriteLine("Enteranumber:");varnum=int.Parse(Console.ReadLine());Console.WriteLine($"Squreof{num}is{num*num}");}}

要在上面的示例中处理可能的异常,请将代码包装在一个try块中,然后在catch块中处理异常,如下所示。

classProgram{staticvoidMain(string[]args){try{Console.WriteLine("Enteranumber:");varnum=int.parse(Console.ReadLine());Console.WriteLine($"Squreof{num}is{num*num}");}catch{Console.Write("Erroroccurred.");}finally{Console.Write("Re-trywithadifferentnumber.");}}}

在上面的示例中,我们将此代码包装在一个try块中。如果try块内发生异常,则程序将跳转到该catch块。在catch块内,我们将显示一条消息以指示用户有关其错误的信息,在finally块内,我们将显示一条有关运行程序后的操作的消息。

try块必须跟catch或finally或两种嵌段。在try不使用块catch或finally块将给出一个编译时错误。

理想情况下,catch块应包含内置或自定义异常类的参数以获取错误详细信息。以下包括Exception捕获所有类型的异常的type参数。

classProgram{staticvoidMain(string[]args){try{Console.WriteLine("Enteranumber:");varnum=int.parse(Console.ReadLine());Console.WriteLine($"Squreof{num}is{num*num}");}catch(Exceptionex){Console.Write("Errorinfo:"+ex.Message);}finally{Console.Write("Re-trywithadifferentnumber.");}}}

异常过滤器

您可以使用catch具有不同异常类型参数的多个块。这称为异常过滤器。当您想以不同的方式处理不同类型的异常时,异常过滤器很有用。

classProgram{staticvoidMain(string[]args){Console.Write("Pleaseenteranumbertodivide100:");try{intnum=int.Parse(Console.ReadLine());intresult=100/num;Console.WriteLine("100/{0}={1}",num,result);}catch(DivideByZeroExceptionex){Console.Write("不能被零除。请再试一次.");}catch(InvalidOperationExceptionex){Console.Write("无效操作。请再试一次.");}catch(FormatExceptionex){Console.Write("不是有效格式。请再试一次.");}catch(Exceptionex){Console.Write("发生错误!请再试一次.");}}}

在上面的示例中,我们指定了catch具有不同异常类型的多个块。我们可以根据错误向用户显示适当的消息,因此用户不会再次重复相同的错误。

注意:
不允许具有相同异常类型的多个catch块。具有基异常类型的catch块必须是最后一个块。

无效的catch块

在同一 try..catch语句中不允许使用无参数catch块和带有Exception参数的catch块,因为它们都执行相同的操作。

try{//可能引发异常的代码}catch//不能同时具有catch和catch(Exception异常){Console.WriteLine("Exceptionoccurred");}catch(Exceptionex)//不能同时具有catch和catch(异常异常){Console.WriteLine("Exceptionoccurred");}

另外,无参数 catch 块 catch {}或通用 catch 块 catch (Exception ex){}必须是最后一个块。如果在 catch {}或 catch (Exception ex)块之后还有其他 catch 块,编译器将给出错误。

示例:无效的catch 捕获

try{//可能引发异常的代码}catch{//该捕获块必须是最后一个块}catch(NullReferenceExceptionnullEx){Console.WriteLine(nullEx.Message);}catch(InvalidCastExceptioninEx){Console.WriteLine(inEx.Message);}

finally 块

finally块是可选块,应在try或catch块之后。无论是否发生异常,都将始终执行 finally 块。finally块通常用于清理代码,例如处理非托管对象。

示例:finally块

staticvoidMain(string[]args){FileInfofile=null;try{Console.Write("Enterafilenametowrite:");stringfileName=Console.ReadLine();file=newFileInfo(fileName);file.AppendText("HelloWorld!")}catch(Exceptionex){Console.WriteLine("Erroroccurred:{0}",ex.Message);}finally{//在这里清理文件对象;file=null;}}
finally不允许使用多个块。另外,finally块不能包含return,continue或break关键字。它不允许控制权离开finally块。

嵌套try-catch

C#允许嵌套try-catch块。当使用嵌套的try-catch块时,将在发生异常catch的try块之后的第一个匹配块中捕获异常。

staticvoidMain(string[]args){vardivider=0;try{try{varresult=100/divider;}catch{Console.WriteLine("Innercatch");}}catch{Console.WriteLine("Outercatch");}}
输出:
Innercatch

catch在上面的示例中,将执行一个内部块,因为它是catch处理所有异常类型的第一个块。

如果没有与抛出的异常类型匹配的内部catch块,则控制将流向外部catch块,直到找到合适的异常筛选器。看下面的实例。

staticvoidMain(string[]args){vardivider=0;try{try{varresult=100/divider;}catch(NullReferenceExceptionex){Console.WriteLine("Innercatch");}}catch{Console.WriteLine("Outercatch");}}
输出:
Outercatch

在上面的示例中,将引发类型异常 DivideByZeroException 。由于内部catch块仅处理NullReferenceTypeException,因此将由外部catch块处理。

编辑于2024-05-20 12:12