throw (C# リファレンス)

プログラムの実行中に例外が発生したことを通知します。

コメント

throw の構文は次のとおりです。

throw [e]

ここで e は、<xref:System.Exception?displayProperty=fullName> から派生したクラスのインスタンスです。 次の例では、GetNumber という名前のメソッドに渡された引数が内部配列の有効なインデックスに対応していない場合に、throw ステートメントを使用して @System.IndexOutOfRangeException をスローします。

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 メソッドによってスローされた例外を処理します。

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

例外の再スロー

throwcatch ブロックで使用すると、catch ブロックで処理された例外を再スローすることもできます。 この場合、throw は例外オペランドを使用しません。 これは、メソッドが呼び出し元から他のライブラリ メソッドに引数を渡し、そのライブラリ メソッドが、呼び出し元に渡す必要がある例外をスローするときに最も役立ちます。 たとえば、次の例では、初期化されていない文字列の最初の文字を取得しようとしたときにスローされた @System.NullReferenceException を再スローします。

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

catch ブロックで throw e 構文を使用すると、呼び出し元に渡す新しい例外をインスタンス化することもできます。 この場合、@System.Exception.Stacktrace プロパティから使用できる、元の例外のスタック トレースが保持されません。

throw

C# 7 以降、throw は、式およびステートメントとして使用できます。 これにより、以前サポートされていなかったコンテキストでの例外のスローが可能になります。 次の設定があります。

  • 条件演算子。 次の例では、throw 式を使用して、メソッドに空の文字列配列が渡された場合に @System.ArgumentException をスローします。 C# 7 より前では、このロジックが 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.");                            
      
    }
    
  • ull 合体演算子。 次の例では、null 合体演算子と共に throw 式を使用して、Name プロパティに割り当てられた文字列が null の場合に例外をスローします。

    public string Name
    {
        get => name;
        set => name = value ?? 
            throw new ArgumentNullException("Name cannot be null", nameof(value));
    }   
    
  • 式形式のラムダまたはメソッド。 次の例では、@System.DateTime 値への変換がサポートされていないため @System.InvalidCastException をスローする、式形式のメソッドを示しています。

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

C# 言語仕様

詳細については、「C# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。

関連項目

C# リファレンス
C# プログラミング ガイド
try-catch
C++ の try、catch、および throw ステートメント
C# のキーワード
例外処理ステートメント
方法: 例外を明示的にスローする