throw(C# 参考)

发出程序执行期间出现异常的信号。

备注

throw 的语法为:

throw [e];

e 是一个派生自 System.Exception 的类的实例。 下例使用 throw 语句在传递给名为 GetNumber 的方法的参数与内部数组的有效索引不对应时引发 IndexOutOfRangeException

using System;

namespace Throw2
{
public class NumberGenerator
{
   int[] numbers = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };

   public int GetNumber(int index)
   {
      if (index < 0 || index >= numbers.Length)
      {
         throw new IndexOutOfRangeException();
      }
      return numbers[index];
   }
}

然后方法调用方使用 try-catchtry-catch-finally 块来处理引发的异常。 下例处理由 GetNumber 方法引发的异常。

using System;

public class Example
{
   public static void Main()
   {
      var gen = new NumberGenerator();
      int index = 10;
      try
      {
          int value = gen.GetNumber(index);
          Console.WriteLine($"Retrieved {value}");
      }
      catch (IndexOutOfRangeException e)
      {
         Console.WriteLine($"{e.GetType().Name}: {index} is outside the bounds of the array");
      }
   }
}
// The example displays the following output:
//        IndexOutOfRangeException: 10 is outside the bounds of the array

重新引发异常

throw 也可以用于 catch 块,以重新引发在 catch 块中处理的异常。 在这种情况下,throw 不采用异常操作数。 当方法将参数从调用方传递给其他库方法时,这是最有用的,库方法引发的异常必须传递给调用方。 例如,以下示例重新引发在尝试检索未初始化字符串的第一个字符时引发的 NullReferenceException

using System;

namespace Throw
{
public class Sentence
{
   public Sentence(string s)
   {
      Value = s;
   }

   public string Value { get; set; }

   public char GetFirstCharacter()
   {
      try
      {
         return Value[0];
      }
      catch (NullReferenceException e)
      {
         throw;
      }
   }
}

public class Example
{
   public static void Main()
   {
      var s = new Sentence(null);
      Console.WriteLine($"The first character is {s.GetFirstCharacter()}");
   }
}
// The example displays the following output:
//    Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
//       at Sentence.GetFirstCharacter()
//       at Example.Main()

重要

还可以使用 catch 块中的 throw e 语法来实例化传递给调用方的新异常。 在这种情况下,将不会保留可从 StackTrace 属性获得的原始异常的堆栈跟踪。

throw 表达式

从 C# 7.0 开始,throw 可以用作表达式和语句。 这允许在以前不支持的上下文中引发异常。 这些方法包括:

  • 条件运算符。 下例使用 throw 表达式在向方法传递空字符串数组时引发 ArgumentException。 在 C# 7.0 之前,此逻辑将需要显示在 if/else 语句中。

    private static void DisplayFirstNumber(string[] args)
    {
       string arg = args.Length >= 1 ? args[0] :
                                  throw new ArgumentException("You must supply an argument");
       if (Int64.TryParse(arg, out var number))
          Console.WriteLine($"You entered {number:F0}");
       else
          Console.WriteLine($"{arg} is not a number.");
    }
    
  • null 合并运算符。 在以下示例中,如果分配给 Name 属性的字符串为 null,则将 throw 表达式与 null 合并运算符结合使用以引发异常。

    public string Name
    {
        get => name;
        set => name = value ??
            throw new ArgumentNullException(paramName: nameof(value), message: "Name cannot be null");
    }
    
  • expression-bodied lambda 或方法。 下例说明了 expression-bodied 方法,由于不支持对 DateTime 值的转换,该方法引发 InvalidCastException

    DateTime ToDateTime(IFormatProvider provider) =>
             throw new InvalidCastException("Conversion to a DateTime is not supported.");
    

C# 语言规范

有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。

请参阅