异常(C# 与 Java)
更新:2007 年 11 月
C# 中的异常处理与 Java 中的异常处理非常相似。
只要在程序执行过程中出现错误,.NET Framework 公共语言运行时 (CLR) 就会创建一个 Exception 对象详细描述此错误。在 .NET Framework 中,Exception 为所有异常类的基类。从 Exception 类派生的异常分为两种类别:SystemException 和 ApplicationException。System 命名空间中的所有类型从 SystemException 派生,而用户定义的异常应从 ApplicationException 派生,以便区分运算时错误和应用程序错误。一些常见的 System 异常包括:
IndexOutOfRangeException:使用了大于数组或集合大小的索引。
NullReferenceException:在将引用设置为有效实例之前使用了引用的属性或方法。
ArithmeticException:操作将导致上溢或下溢。
FormatException:参数或操作数格式不正确。
与 Java 一样,如果代码可能导致异常,则将此代码置于 try 块内。紧跟在该块之后的一个或多个 catch 块提供错误处理。此外还可以对不管是否会引发异常都要执行的任何代码使用 finally 块。有关更多信息,请参见 try-catch(C# 参考) 和 try-catch-finally(C# 参考)。
使用多个 catch 块时,捕捉到的异常必须按照普遍性递增的顺序放置,因为只有与引发的异常相匹配的第一个 catch 块将被执行。C# 编译器对此作了强制规定,而 Java 编译器则未作强制规定。
此外,C# 不像 Java 那样需要对 catch 块使用参数;在没有参数的情况下,catch 块也适用于 Exception 类。
例如,读取文件时可能遇到 FileNotFoundException 或 IOException 异常,并且您希望将含义更明确的 FileNotFoundException 处理程序放置在第一位,如以下代码所示:
try
{
// code to open and read a file
}
catch (System.IO.FileNotFoundException e)
{
// handle the file not found exception first
}
catch (System.IO.IOException e)
{
// handle any other IO exceptions second
}
catch
{
// a catch block without a parameter
// handle all other exceptions last
}
finally
{
// this is executed whether or not an exception occurs
// use to release any external resources
}
通过从 Exception 派生,可以创建您自己的异常类。例如,下面的代码创建一个可能引发的 InvalidDepartmentException 类(例如,如果为新的 Employee 提供的部门无效)。用户定义的异常的类构造函数使用 base 关键字来调用基类构造函数,并发送相应的消息:
public class InvalidDepartmentException : System.Exception
{
public InvalidDepartmentException(string department) : base("Invalid Department: " + department)
{
}
}
接着可以使用以下代码引发一个异常:
class Employee
{
private string department;
public Employee(string department)
{
if (department == "Sales" || department == "Marketing")
{
this.department = department;
}
else
{
throw new InvalidDepartmentException(department);
}
}
}
C# 不支持选中的异常。在 Java 中,这些选中的异常使用 throws 关键字进行声明,从而指定方法可以引发必须由调用代码处理的特定类型异常。