throw(C# 参考)throw (C# Reference)

发出程序执行期间出现异常的信号。Signals the occurrence of an exception during program execution.

备注Remarks

throw 的语法为:The syntax of throw is:

throw [e];

e 是一个派生自 System.Exception 的类的实例。where e is an instance of a class derived from System.Exception. 下例使用 throw 语句在传递给名为 IndexOutOfRangeException 的方法的参数与内部数组的有效索引不对应时引发 GetNumberThe following example uses the throw statement to throw an IndexOutOfRangeException if the argument passed to a method named GetNumber does not correspond to a valid index of an internal array.

using System;

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 块来处理引发的异常。Method callers then use a try-catch or try-catch-finally block to handle the thrown exception. 下例处理由 GetNumber 方法引发的异常。The following example handles the exception thrown by the GetNumber method.

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

重新引发异常Re-throwing an exception

throw 也可以用于 catch 块,以重新引发在 catch 块中处理的异常。throw can also be used in a catch block to re-throw an exception handled in a catch block. 在这种情况下,throw 不采用异常操作数。In this case, throw does not take an exception operand. 当方法将参数从调用方传递给其他库方法时,这是最有用的,库方法引发的异常必须传递给调用方。It is most useful when a method passes on an argument from a caller to some other library method, and the library method throws an exception that must be passed on to the caller. 例如,以下示例重新引发在尝试检索未初始化字符串的第一个字符时引发的 NullReferenceExceptionFor example, the following example re-throws an NullReferenceException that is thrown when attempting to retrieve the first character of an uninitialized string.

using System;

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()

重要

还可以使用 throw e 块中的 catch 语法来实例化传递给调用方的新异常。You can also use the throw e syntax in a catch block to instantiate a new exception that you pass on to the caller. 在这种情况下,将不会保留可从 StackTrace 属性获得的原始异常的堆栈跟踪。In this case, the stack trace of the original exception, which is available from the StackTrace property, is not preserved.

throw 表达式The throw expression

从 C# 7.0 开始,throw 可以用作表达式和语句。Starting with C# 7.0, throw can be used as an expression as well as a statement. 这允许在以前不支持的上下文中引发异常。This allows an exception to be thrown in contexts that were previously unsupported. 这些方法包括:These include:

  • 条件运算符the conditional operator. 下例使用 throw 表达式在向方法传递空字符串数组时引发 ArgumentExceptionThe following example uses a throw expression to throw an ArgumentException if a method is passed an empty string array. 在 C# 7.0 之前,此逻辑将需要显示在 if/else 语句中。Before C# 7.0, this logic would need to appear in an if/else statement.

    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 合并运算符the null-coalescing operator. 在以下示例中,如果分配给 throw 属性的字符串为 Name,则将 null 表达式与 null 合并运算符结合使用以引发异常。In the following example, a throw expression is used with a null-coalescing operator to throw an exception if the string assigned to a Name property is null.

    public string Name
    {
        get => name;
        set => name = value ?? 
            throw new ArgumentNullException(paramName: nameof(value), message: "Name cannot be null");
    }   
    
  • expression-bodied lambda 或方法。an expression-bodied lambda or method. 下例说明了 expression-bodied 方法,由于不支持对 InvalidCastException 值的转换,该方法引发 DateTimeThe following example illustrates an expression-bodied method that throws an InvalidCastException because a conversion to a DateTime value is not supported.

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

C# 语言规范C# language specification

有关详细信息,请参阅 C# 语言规范For more information, see the C# Language Specification. 该语言规范是 C# 语法和用法的权威资料。The language specification is the definitive source for C# syntax and usage.

另请参阅See also