C# Fundamental Knowledge - Exception

·

1 min read

Exception 类型

  • ArrayTypeMismatchException:由于元素的实际类型与数组的实际类型不兼容而导致数组无法存储给定元素时引发。

  • DivideByZeroException:试图将整数值除以零时引发。

    根据 IEEE 754 算法的规则,将浮点值除以零不会引发异常,而是会产生正无穷大、负无穷大或“非数值”(NaN)。

  • IndexOutOfRangeException:索引小于零或超出数组边界时,试图对数组编制索引时引发。

  • InvalidCastException:从基类型显式转换为接口或派生类型在运行时失败时引发。

  • NullReferenceException:试图引用值为 null 的对象时引发。

  • OverflowException:选中的上下文中的算术运算溢出时引发。

  • ArgumentExceptionArgumentNullException:使用无效的参数值或 null 引用调用方法或构造函数时,使用这些异常类型。

  • InvalidOperationException:当方法的操作条件不支持成功完成特定方法调用时,使用此异常类型。

  • NotSupportedException:当不支持某个操作或功能时,使用此异常类型。

  • IOException:输入/输出操作失败时,使用此异常类型。

  • FormatException:字符串或数据的格式不正确时,使用此异常类型。

捕获特定异常

System.Exception 是所有派生异常类型从其继承的基类。 每个异常类型通过特定的类层次结构从基类继承。

例如,InvalidCastException 类层次结构如下所示:

Object
    Exception
        SystemException
            InvalidCastException

Exception 类的属性:

  • Data:Data 属性保存键值对中的任意数据。

  • HelpLink:HelpLink 属性可用于保存指向帮助文件的 URL(或 URN),帮助文件中提供了大量信息说明了异常的原因。

  • HResult:HResult 属性可用于访问分配给特定异常的编码数值。

  • InnerException:在处理异常时 InnerException 属性可用于创建和保留一系列异常。

  • Message:Message 属性提供有关异常原因的详细信息。

  • Source:Source 属性可用于访问导致错误的应用程序或对象的名称。

  • StackTrace:StackTrace 属性包含可用于确定错误位置的堆栈跟踪。

  • TargetSite:TargetSite 属性可用于获取引发当前异常的方法。

示例

看下面这段代码

static void Process1()
{
    try
    {
        WriteMessage();
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception caught in Process1: {ex.Message}");
    }
}

虽然可以在没有参数的情况下使用 catch 子句,但不建议使用这种方法。 如果未指定参数,则会捕获所有异常类型,并且无法区分它们。

一般情况下,只应捕获代码知道如何从中恢复的异常。 因此,catch 子句应指定一个派生自 System.Exception 的对象参数。 异常类型应尽可能具体。 这有助于避免捕获异常处理程序无法解决的异常。

扩展:

执行将一个整型类型的值分配给另一个整型类型的整型类型计算时,结果取决于溢出检查上下文。 在 checked 上下文中,如果源值在目标类型的范围内,则转换成功。 否则会引发 OverflowException。 在未检查的上下文中,转换始终成功,并按如下方式进行:

  • 如果源类型大于目标类型,则通过放弃其“额外”最高有效位来截断源值。 结果会被视为目标类型的值。

  • 如果源类型小于目标类型,则源值是符号扩展或零扩展,以使其与目标类型的大小相同。 如果源类型带符号,则是符号扩展;如果源类型是无符号的,则是零扩展。 结果会被视为目标类型的值。

  • 如果源类型与目标类型的大小相同,则源值将被视为目标类型的值。

      static void WriteMessage()
      {
          double float1 = 3000.0;
          double float2 = 0.0;
          int number1 = 3000;
          int number2 = 0;
          byte smallNumber;
    
          Console.WriteLine(float1 / float2);
          checked
          {
              smallNumber = (byte)number1; // 加了 checked 块会抛出 OverflowException 异常
          }
      }