1 次元配列 (C# プログラミング ガイド) | MSDN
// 1次元配列の宣言 int[] array1 = new int[5]; // 初期化を伴う宣言 int[] array2 = new int[] { 1, 2, 3 }; int[] array3 = new[] { 1, 2, 3 }; // ... 代替の構文 int[] array4 = { 1, 2, 3 };
newを省略する代替の構文は、宣言時にのみ使用できます。なおIEnumerableを実装するコレクションは、コレクション初期化子で初期化できます。
int[] array2; array2 = new int[] { 1, 2, 3 }; // OK array2 = new[] { 1, 2, 3 }; // OK int[] array4; array4 = { 1, 2, 3 }; // エラー CS1525 '{' は無効です。
初期化しない場合、値型は既定値に、参照型はnullに初期化されます。
int[] p1 = new int[10]; // 値型 (Int32構造体) Point[] p2 = new Point[10]; // 値型 (Point構造体) MyClass[] p3 = new MyClass[10]; // 参照型 (クラス) Console.Write(p1[0]); // 0 Console.Write(p2[0]); // {X = 0 Y = 0} Console.Write(p3[0]); // null
要素数を負数とすると、OverflowException例外が発生します。
int size = -1;
int[] p = new int[size]; // System.OverflowException はハンドルされませんでした。「算術演算の結果オーバーフローが発生しました。」
// 2次元配列の宣言 int[,] array1 = new int[2, 3]; // 2行3列の配列 // 初期化を伴う宣言 int[,] array2 = { { 1, 2, 3 }, { 4, 5, 6 } }; // 2次元配列へのアクセス Console.Write(array2[1, 2]); // 6
// 3次元配列の宣言 int[,,] array3 = new int[2, 3, 4]; Console.Write( array3.Rank ); // 3
CreateInstance()を用いて、次のように作成することもできます。この方法では参照型の要素はnullに、値型のそれは0に初期化されます。
int[,] a2 = (int[,]) Array.CreateInstance(typeof(int), 2, 3); int[,,] a3 = (int[,,])Array.CreateInstance(typeof(int), 2, 3, 4);Array.CreateInstance メソッド (Type, Int32, Int32) (System) | MSDN
int[,] array1 = new int[2, 3]; Console.Write( array1.Rank ); // 次元数:2 Console.Write( array1.Length ); // 要素の総数:6 Console.Write( array1.GetLength(0) ); // 要素数:2 Console.Write( array1.GetLength(1) ); // 要素数:3
多次元配列を用いると、コード分析によって「複数次元の配列ではなくジャグ配列を使用します」としてCA1814で警告されます。これは多次元配列では領域が無駄になることがあることを警告するものですが、その恐れがないならば無視しても問題ありません。
ジャグ配列とは配列を要素に持つ配列で、それぞれの要素の配列はサイズが異なっていても構いません。ジャグ配列 (C# プログラミング ガイド) | MSDN
// ジャグ配列の宣言 int[][] array1 = new int[3][]; // array1[0] = new int[] { 1, 2, 3, 4 }; array1[1] = new int[] { 5, 6 }; array1[2] = new int[] { 7, 8, 9 }; // 初期化を伴う宣言 int[][] array2 = new int[][] { new int[] { 1, 2, 3, 4 }, new int[] { 5, 6 }, new int[] { 7, 8, 9 } }; // ジャグ配列へのアクセス Console.Write( array2[2][1] ); // 8
// 3次元配列の宣言 int[][][] array3 = new int[2][][]; array3[0] = new int[2][]; array3[1] = new int[2][]; array3[0][0] = new int[] { 1, 2 }; array3[0][1] = new int[] { 3, 4 }; array3[1][0] = new int[] { 5, 6 }; array3[1][1] = new int[] { 7, 8 }; Console.Write(array3[0][0][1]); // 2 Console.Write(array3[0][1][0]); // 3 Console.Write(array3[1][0][0]); // 5 // 初期化を伴う宣言 int[][][] array4 = new int[][][] { new int[][] { new int[] { 1, 2 }, new int[] { 3, 4 }, }, new int[][] { new int[] { 5, 6 }, new int[] { 7, 8 }, } };
ジャグ配列では次元数を表すRankはつねに1、すべての要素数を表すLengthは最初の配列の要素数となります。
int[][] array1 = new int[3][]; Console.Write( array1.Rank ); // 1 Console.Write( array1.Length ); // 3 Console.Write( array1.GetLength(0) ); // 3 array1[0] = new int[] { 1, 2 }; Console.Write( array1[0].Rank ); // 1 Console.Write( array1[0].Length ); // 2 Console.Write( array1[0].GetLength(0) ); // 2
過度に大きなサイズの配列を生成しようとすると、OutOfMemoryException例外が発生します。32ビット アプリケーションでは1つのオブジェクトの上限が2GBで、64ビットも既定では2GBです。Remarks - OutOfMemoryException Class (System) | MSDN
byte[] a = new byte[1024 * 1024 * (1024 + 512)]; // System.OutOfMemoryException
この上限は、64ビット環境ではgcAllowVeryLargeObjectsを指定することで拡大できます。<gcAllowVeryLargeObjects> 要素 | MSDN
IEnumerableを実装するため、ArrayやArrayListでもforeachを使えます。
int[] array = new int[] { 1, 2, 3 };
foreach (int x in array)
{
Console.Write(x);
}
// 123
1次元と同様の方法で、すべての要素を反復処理できます。ただし1次元に配置されているかのように処理されるため、それが意図したものでなければforループで記述します。配列での foreach の使用 (C# プログラミング ガイド) | MSDN
int[,] array = { { 1, 2, 3 }, { 4, 5, 6 } };
foreach (int x in array)
{
Console.Write(x);
}
// 123456
ジャグ配列の要素は配列のため、foreachをネストします。
int[][] array = new int[][]
{
new int[] { 1, 2, 3, 4 },
new int[] { 5, 6 }
};
foreach (int[] a in array)
{
foreach (int x in a)
{
Console.Write(x);
}
}
// 123456