以下是我编写的代码,用于了解异常处理的工作原理:
using System;
using System.IO;
class ExceptionHandling
{
public static void Main()
{
try
{
StreamReader streamReader = new StreamReader("C:\\Sample Files\\Data.txt");
Console.WriteLine(streamReader.ReadToEnd());
streamReader.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
我了解try
块,但我很难理解catch
块的工作原理。我知道Exception
是class
,ex.Message
是例外消息。
ex
是什么?如果这是一个对象,那么我们如何在没有实例化的情况下使用?将Exception ex放入catch的参数中会做什么? try
和catch
方法?如果是,那么它们是否在System
名称空间?答案 0 :(得分:5)
ex
是Exception
类型的变量。
当其他地方的代码失败时,它会执行throw new Exception("some message here");
。
throw
关键字导致异常(由new
创建)在堆栈中向上传递,如果它到达catch
,则该代码将以ex
执行指向那个异常对象。
throw
,try
和catch
不是功能,而是关键字。它们是foreach
和if
等语言功能。
答案 1 :(得分:4)
ex
是一个引用异常对象的变量,该异常对象由引发异常的对象,其依赖项之一或.NET运行时实例化。
您可以像任何对象一样创建自己的异常,然后抛出它们:
var myException = new MyCustomException(/*...*/);
throw myException;
try-catch是一个语句,它是C#语言语法的一部分。
如果您不需要访问处理代码中的任何成员,catch
部分不需要引用异常变量。以下是有效的语法:
try {
// some code that might throw IO exception
catch (IOException) {
Console.WriteLine("Exception thrown.");
}
奖金提示:
Exception
通常是不好的做法 - 您通常应catch the most specific derived exception尝试在catch
条款中处理。IDisposable
的类StreamReader
时,应考虑使用using
statement。答案 2 :(得分:2)
如果代码在任何地方崩溃,因为有人已实例化并抛出(C#throw
关键字)Exception
的实例(很可能是InvalidOperationException
这样的子类型)。
如果在try
内引发此异常,catch
将尝试通过检查是否可以从Exception
(所有.Net异常都这样做)派生它来处理它。
如果定义一个变量来保存catch块上的异常实例,运行时将为其分配异常。
因此运行时将ex
设置为发生的异常。看看使用Debugger查看有关它的更多信息。
你可以像这样处理特定的例外:
catch (NullReferenceException nre) { HandleNRE(nre); } //nre will be a NullReferenceException
catch (InvalidOperationException ioe) { HandleIOE(ioe); } //ioe will be an InvalidOperationException
catch (Exception e) { HandleEverythingElse(e); } //e will be whatever was thrown.
你也可以拥有没有ex
的catch块,例如
catch (NullReferenceException) { /* Do nothing, who cares about nulls. */ }