ArgumentOutOfRangeException の原因と直し方
List<T>のインデクサに範囲外の値を渡すと発生します。配列のIndexOutOfRangeExceptionとは異なる例外クラスです。
エラーメッセージの読み方
Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
System- 名前空間 — System なら標準の基本例外です
ArgumentOutOfRangeException- 例外クラス — 何が起きたか。ここを検索するのが最短です
Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')- 詳細メッセージ — どの値が問題だったか
at Program.Main(String[] args) in Program.cs:line 4- 発生箇所 — スタックトレースの先頭行
このエラーが出る典型パターン
パターン1
1 class Program { 2 static void Main(string[] args) { 3 var nums = new System.Collections.Generic.List<int> { 1, 2, 3 }; 4 System.Console.WriteLine(nums[5 ]); ^ 5 } 6 }
Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
at Program.Main(String[] args) in Program.cs:line 4
List<T>のインデクサは配列と違い、範囲外を指定するとArgumentOutOfRangeExceptionを投げます(配列のIndexOutOfRangeExceptionとは型が違います)。
直し方: 5 を 1 にします。
広告
広告スロット(未設定)
パターン2
1 class Program { 2 static void Main(string[] args) { 3 var nums = new System.Collections.Generic.List<int> { 1, 2, 3 }; 4 int idx = -1; ^ 5 System.Console.WriteLine(nums[idx]); 6 } 7 }
Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
at Program.Main(String[] args) in Program.cs:line 5
負のインデックスも同様にArgumentOutOfRangeExceptionになります。
直し方: -1 を 0 にします。
パターン3
1 class Program { 2 static void Main(string[] args) { 3 var names = new System.Collections.Generic.List<string> { "a", "b" }; 4 System.Console.WriteLine(names[2 ]); ^ 5 } 6 }
Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
at Program.Main(String[] args) in Program.cs:line 4
要素数2のリストで有効なインデックスは0と1だけです。Countと最大インデックスを混同しないようにします。
直し方: 2 を 1 にします。
よくある誤解
配列とList<T>は似ていますが、範囲外アクセス時に投げる例外の型が違います。catchするときはこの違いに注意が必要です。
まとめ
ArgumentOutOfRangeExceptionは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。