【C#】.NETからの例外エラーが発生するコードサンプル

# はじめに

.NETのラムタイムからスローされる例外クラスのリファレンスに記述されている発生例のコードを参考に、サンプルコードをまとめてみました。本記事は以下の例外について記述してます。

| 例外 | 説明 |
| --- | --- |
| [ArrayTypeMismatchException](https://learn.microsoft.com/ja-jp/dotnet/api/system.arraytypemismatchexception) | 要素の実際の型が配列の実際の型に対応していないことが原因で、指定された要素を配列に格納できない場合にスローされます。 |
| [DivideByZeroException](https://learn.microsoft.com/ja-jp/dotnet/api/system.dividebyzeroexception) | 整数値のゼロ除算が試行されたときにスローされます。 |
| [IndexOutOfRangeException](https://learn.microsoft.com/ja-jp/dotnet/api/system.indexoutofrangeexception) | インデックスがゼロよりも小さい場合またはインデックスが配列の境界外にある場合に、配列のインデックス作成が試行されたときにスローされます。 |
| [InvalidCastException](https://learn.microsoft.com/ja-jp/dotnet/api/system.invalidcastexception) | 基本データ型からインターフェイスまたは派生型への明示的な変換が実行時に失敗したときにスローされます。 |
| [NullReferenceException](https://learn.microsoft.com/ja-jp/dotnet/api/system.nullreferenceexception) | 値が null であるオブジェクトを参照しようとするとスローされます。 |
| [OutOfMemoryException](https://learn.microsoft.com/ja-jp/dotnet/api/system.outofmemoryexception) | new 演算子を使用したメモリの割り当てに失敗するとスローされます。 この例外は、共通言語ランタイムに使用できるメモリが足りなくなったことを示します。 |
| [OverflowException](https://learn.microsoft.com/ja-jp/dotnet/api/system.overflowexception) | checked コンテキストで算術演算がオーバーフローしたときにスローされます。 |
| [StackOverflowException](https://learn.microsoft.com/ja-jp/dotnet/api/system.stackoverflowexception) | 保留中のメソッド呼び出しが多すぎることが原因で実行スタックが不足したときにスローされます。通常は、非常に深い再帰か無限再帰があることを示します。 |
| [TypeInitializationException](https://learn.microsoft.com/ja-jp/dotnet/api/system.typeinitializationexception) | 静的コンストラクターが例外をスローし、その例外をキャッチするための対応する catch 句がない場合にスローされます。 |

https://learn.microsoft.com/ja-jp/dotnet/csharp/fundamentals/exceptions/compiler-generated-exceptions

# サンプルコード

各例外クラスのリファレンスにあるサンプルコードをもとにサンプルコードを記述しました。

## ArrayTypeMismatchException

誤った型の要素を配列内に格納しようとした場合にスローされる例外。

```csharp
string[] names = {"Dog", "Cat", "Fish"};
Object[] objs  = (Object[]) names;
Object obj = (Object) 13;
objs[2] = obj;  //Exception:別の型を代入している
foreach (object animalName in objs)
{
    Console.WriteLine(animalName);
}
```

## DivideByZeroException

整数または Decimal 値を 0 で除算しようとするとスローされる例外。

```csharp
int number1 = 3000;
int number2 = 0;
int number3 = number1 / number2; //Exception:0で割っている
Console.WriteLine(number3);
```

## IndexOutOfRangeException

境界外のインデックスを使用して配列またはコレクションの要素にアクセスしようとしたときにスローされる例外。

```csharp
List<Char> characters = new List<Char>();
characters.InsertRange(0, new Char[] { 'a', 'b', 'c', 'd', 'e', 'f' } );
for (int ctr = 0; ctr <= characters.Count; ctr++) //Exception:配列外参照している
    Console.Write("'{0}'    ", characters[ctr]);
```

## ****InvalidCastException****

無効なキャストまたは明示的な変換が発生したときにスローされる例外。

```csharp
bool flag = true;
Char ch = Convert.ToChar(flag); //Exception:変換不可なキャストをした
Console.WriteLine(ch);
```

## NullReferenceException

null オブジェクト参照を逆参照しようとした場合にスローされる例外。

```csharp
int value = 0;
List<String> names=null;
if (value > 0)
    names = new List<String>();

names.Add("Major Major Major"); //Exception:nullのまま参照した
```

## OutOfMemoryException

プログラムの実行を継続するためのメモリが不足している場合にスローされる例外。

```csharp
using System.Text;
StringBuilder sb = new StringBuilder(15, 15);
sb.Append("Substring #1 ");
try {
    sb.Insert(0, "Substring #2 ", 1);  //Exception:上限15文字を超えた
}
catch (OutOfMemoryException e) {
    Console.WriteLine("Out of Memory: {0}", e.Message);
}
```

## OverflowException

checked コンテキストの算術演算、キャスト演算、または変換演算でオーバーフローが発生するとスローされる例外。

```csharp
int value = 780000000;
checked {
try {
   // Square the original value.
   int square = value * value;   //Exception:Intの最大数2,147,483,647を超えた
   Console.WriteLine("{0} ^ 2 = {1}", value, square);
}
catch (OverflowException) {
   double square = Math.Pow(value, 2);
   Console.WriteLine("Exception: {0} > {1:E}.",
                     square, Int32.MaxValue);
} }
// The example displays the following output:
//       Exception: 6.084E+17 > 2.147484E+009.
```

## StackOverflowException

実行スタックがスタック サイズを超えるとスローされる例外。無限ループや無限再帰などで発生します。

```csharp
const int MAX_RECURSIVE_CALLS = 10000;  //再起関数の実行数
int ctr = 0;
Execute();
Console.WriteLine("\nThe call counter: {0}", ctr);

void Execute()
{
    ctr++;
    if (ctr % 50 == 0)
        Console.WriteLine("Call number {0} to the Execute method", ctr);

    if (ctr <= MAX_RECURSIVE_CALLS)
        Execute();  //Exception:スタックサイズを超えたらエラー
        
    ctr--;
}
```

## TypeInitializationException

クラス初期化子によってスローされた例外をラップするラッパーとしてスローされる例外。 このクラスは継承できません。

次の例は、 TypeInitializationException コンパイラによって生成された静的コンストラクターによってスローされる例外を示しています。 Exampleクラスでstaticで定義された、TestClassクラスの初期値に 3 を入れたことで ArgumentOutOfRangeExceptionが発生します。 この例外は処理されないため、例外で TypeInitializationException ラップされます。
```csharp
Example.Main();

public class Example
{
   private static TestClass test = new TestClass(3); //Exception:staticで例外が発生した
   
   public static void Main()
   {
      Example ex = new Example();
      Console.WriteLine(test.Value);
   }
}

public class TestClass
{
   public readonly int Value;
   
   public TestClass(int value)
   {
      if (value < 0 || value > 1) throw new ArgumentOutOfRangeException();
      Value = value;
   }
}
// The example displays the following output:
//    Unhandled Exception: System.TypeInitializationException: 
//       The type initializer for 'Example' threw an exception. ---> 
//       System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
//       at TestClass..ctor(Int32 value)
//       at Example..cctor()
//       --- End of inner exception stack trace ---
//       at Example.Main()
```