throw (Справочник по C#)

C Sharp > throw (Справочник по C#)
06.02.2018 16:31:28



Статья:

Примечания

Синтаксис throw выглядит следующим образом:

C#
throw [e]

где e — это экземпляр класса, производного от System.Exception. В следующем примере используется оператор throw для создания IndexOutOfRangeException, если аргумент, переданный в метод с именем GetNumber, не соответствует допустимому индексу внутреннего массива.

C#
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-catch или try-catch-finally для обработки исключения. В следующем примере показана обработка исключения, созданного методом GetNumber.

C#
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, возникающее при попытке получить первый символ неинициализированной строки.

C#
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, чтобы создать исключение, которое будет передано вызывающему объекту. В этом случае трассировка стека исходного исключения, которое доступно из свойства StackTrace, не сохраняется.

Выражение throw

Начиная с C# 7 throw можно использовать в качестве выражения, а также как оператор.Это позволяет вызывать исключения в контекстах, которые ранее не поддерживались. Сюда входит следующее.

  • Условный оператор. В следующем примере используется исключение throw для создания ArgumentException, если методу передается массив пустых строк. До выхода C# 7 эта логика должна была отображаться в инструкции if/else.

    C#
    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. В следующем примере выражение throwиспользуется с оператором, принимающим значение NULL, для создания исключения, если строка, назначенная свойству Name является null.

    C#
    public string Name
    {
        get => name;
        set => name = value ?? 
            throw new ArgumentNullException("Name cannot be null", nameof(value));
    }   
    
  • Метод или лямбда, воплощающие выражение. В следующем примере показан метод, воплощающий выражение, который создает InvalidCastException, так как преобразование в значение DateTime не поддерживается.

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