详解C#编程中异常的创建和引发以及异常处理

2019-12-26 17:38:34丽君

引发异常时要避免的情况
下表确定了在引发异常时要避免的做法:

  • 不应使用异常来更改正常执行过程中的程序流程。异常只能用于报告和处理错误条件。
  • 只能引发异常,而不能作为返回值或参数返回异常。
  • 不要从自己的源代码中有意引发 System.Exception、System.SystemException、System.NullReferenceException 或 System.IndexOutOfRangeException。
  • 不要创建可在调试模式下引发但不会在发布模式下引发的异常。若要在开发阶段确定运行时错误,请改用调试断言。

    定义异常类

    程序可以引发 System 命名空间中的预定义异常类(前面注明的情况除外),或通过从 Exception 派生来创建它们自己的异常类。派生类至少应定义四个构造函数:一个是默认构造函数,一个用来设置消息属性,一个用来设置 Message 属性和 InnerException 属性。第四个构造函数用于序列化异常。新异常类应该可序列化。例如:

    
    public class InvalidDepartmentException : System.Exception
    {
      public InvalidDepartmentException() : base() { }
      public InvalidDepartmentException(string message) : base(message) { }
      public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }
    
      // A constructor is needed for serialization when an
      // exception propagates from a remoting server to the client. 
      protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info,
        System.Runtime.Serialization.StreamingContext context) { }
    }
    
    

    仅当新属性提供的数据有助于解决异常时,才应将其添加到异常类。如果向派生的异常类添加了新属性,则应重写 ToString() 以返回添加的信息。

     


    异常处理
    C# 程序员可使用 try 块对可能受异常影响的代码进行分区。关联的 catch 块用于处理任何结果异常。一个包含代码的 finally 块,无论 try 块中是否引发异常(例如,释放在 try 块中分配的资源),这些代码都会运行。一个 try 块需要一个或多个关联的 catch 块或一个 finally 块,或两者。
    以下示例给出了一个 try-catch 语句,一个 try-finally 语句,和一个 try-catch-finally 语句。

    
     try
    {
      // Code to try goes here.
    }
    catch (SomeSpecificException ex)
    {
      // Code to handle the exception goes here.
      // Only catch exceptions that you know how to handle.
      // Never catch base class System.Exception without
      // rethrowing it at the end of the catch block.
    }
    
     try
    {
      // Code to try goes here.
    }
    finally
    {
      // Code to execute after the try block goes here.
    }
    
     try
    {
      // Code to try goes here.
    }
    catch (SomeSpecificException ex)
    {
      // Code to handle the exception goes here.
    }
    finally
    {
      // Code to execute after the try (and possibly catch) blocks 
      // goes here.
    }