配列

配列の作成

1次元配列

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 はハンドルされませんでした。「算術演算の結果オーバーフローが発生しました。」

多次元配列 (Multidimensional Array) / n次元配列 (矩形配列)

多次元配列 (C# プログラミング ガイド) | MSDN

// 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で警告されます。これは多次元配列では領域が無駄になることがあることを警告するものですが、その恐れがないならば無視しても問題ありません。

ジャグ配列 (Jagged Array) / 配列の配列

ジャグ配列とは配列を要素に持つ配列で、それぞれの要素の配列はサイズが異なっていても構いません。ジャグ配列 (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

foreachステートメント

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

コレクションとの変換

List<T>との変換

参考

参考書

Microsoft Learnから検索