zoukankan      html  css  js  c++  java
  • 异常处理

    为了写一个支持异常处理的程序,需要做一下两件事情:

    1. 代码放到一个try块中。代码运行时,它会尝试执行try块内的所有语句。如果没有任何语句产生异常,这些语句将一个接一个运行,直到全部完成。然而,一旦出现异常,就会跳出try块,并进入一个catch处理程序中执行。

    2. 在try块后写一个或多个catch处理程序,用他们处理任何发生的错误。每个catch处理程序都负责捕捉并处理一种特定类型的异常,可以写多个catch处理程序。Try块中任何一个语句造成错误,“运行时”都会生成并抛出一个异常。然后,“运行时”将检查try块之后的catch处理程序,将控制权移交给一个匹配的处理程序。

    Eg:

    class ExceptionTest

    {

    static double SafeDivision(double x, double y)

    {

    if (y == 0)

    throw new System.DivideByZeroException();

    return x / y;

    }

    static void Main()

    {

    // Input for test purposes. Change the values to see

    // exception handling behavior.

    double a = 98, b = 0;

    double result = 0;

    try

    {

    result = SafeDivision(a, b);

    Console.WriteLine("{0} divided by {1} = {2}", a, b, result);

    }

    catch (DivideByZeroException e)

    {

    Console.WriteLine("Attempted divide by zero.");

    }

    }

    }

    异常用于指示在运行程序时发生了错误。此时将创建一个描述错误的异常对象,然后使用 throw 关键字“引发”该对象。然后运行时搜索最兼容的异常处理程序。

    当存在下列一种或多种情况时,程序员应引发异常:

    • 方法无法完成其中定义的功能。

    例如,如果方法的参数具有无效值:

    static void CopyObject(SampleClass original)

    {

    if (original == null)

    {

    throw new System.ArgumentException("Parameter cannot be null", "original");

    }

    }

    • 根据对象的状态,对某个对象进行不适当的调用。

    一个示例可能尝试对只读文件执行写操作。在对象状态不允许某项操作的情况下,引发 InvalidOperationException 的一个实例或基于此类的派生类的对象。以下为引发 InvalidOperationException 对象的方法的示例:

    C#

    复制

    class ProgramLog

    {

    System.IO.FileStream logFile = null;

    void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}

    void WriteLog()

    {

    if (!this.logFile.CanWrite)

    {

    throw new System.InvalidOperationException("Logfile cannot be read-only");

    }

    // Else write data to the log and return.

    }

    }

    • 方法的参数导致了异常。

    在此情况下,应捕获原始异常并创建一个 ArgumentException 实例。原始异常应作为 InnerException 参数传递给 ArgumentException 的构造函数:

    C#

    复制

    static int GetValueFromArray(int[] array, int index)

    {

    try

    {

    return array[index];

    }

    catch (System.IndexOutOfRangeException ex)

    {

    System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index", ex);

    throw argEx;

    }

    }

    异常包含一个名为 StackTrace 的属性。此字符串包含当前调用堆栈上的方法的名称,以及为每个方法引发异常的位置(文件名和行号)。StackTrace 对象由公共语言运行时 (CLR) 从 throw 语句点开始自动创建,因此必须从堆栈跟踪的开始点引发异常。

    所有异常都包含一个名为 Message 的属性。应该设置此字符串来解释发生异常的原因。注意,不应将安全敏感信息放在消息文本中。除 Message 之外,ArgumentException 还包含一个名为 ParamName 的属性,应将该属性设置为导致引发异常的参数的名称。对于属性设置器,ParamName 应设置为 value。

    公共的受保护方法应在其无法完成预期功能时引发异常。引发的异常类应该是符合错误条件的最确切的可用异常。这些异常应编写为类功能的一部分,派生类或对原始类的更新应保留相同的行为,以实现向后兼容性。有关更多信息,请参见 异常设计准则

    引发异常时要避免的情况


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

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

    定义异常类


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

    C#

    复制

    [Serializable()]

    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() 以返回添加的信息。

    Checked和unchecked整数运算

    编写checked语句:

    Checked语句是指以checked关键字开头的一个代码块。Checked语句中的任何整数运算溢出,都会抛出一个OverflowException异常,如下所示:

    int number = int.MaxValue;

    checked

    {

    int willThrow = number++;

    Console.WriteLine("永远不会执行到这");

    }

    还可以使用unchecked关键字创建一个强制不检查溢出的语句块。一个unchecked块中的所有整数运算都不会检查,永远不会抛出OverflowExpception异常。例如:

    int number = int.MaxValue;

    unchecked

    {

    int wontThrow = number++;

    Console.WriteLine("会执行到这");

    }

    使用checked与unchecked关键字,还可以控制对单独的整数表达式的溢出检查。

    Int wontThrow = unchecked(int.MaxValue + 1);

    Int willThrow = checked(int.MaxValue + 1);

     

     

    以上文字部分来源于MSDN

  • 相关阅读:
    简单工厂模式
    单例模式
    Quartz.NET总结(三)Quartz 配置
    Quartz.NET总结(二)CronTrigger和Cron表达式
    ORACLE跨数据库查询的方法
    github使用个人总结
    ffmpeg 下载安装和简单应用
    Python 安装与环境变量配置
    Sublime text 3 汉化教程
    给大家分享两套WordPress收费主题
  • 原文地址:https://www.cnblogs.com/bacazy/p/2883895.html
Copyright © 2011-2022 走看看