C#でプログラミングをしていると、「配列を素早く初期化したい」「同じ値で配列を埋めたい」といった場面に出くわしますよね。
配列の初期化方法は、C#のバージョンアップとともに進化してきました。最新のC# 12では、さらに簡潔で読みやすい書き方が追加されています。
今回は、C#で配列を一括初期化する様々な方法を、基本から最新機能まで詳しく解説していきます。
配列とは
まず、配列の基本を確認しておきましょう。
配列の特徴
配列は、同じ型のデータを複数まとめて扱うためのデータ構造です。
配列の主な特徴:
- 同じデータ型の要素を連続して格納
- 0から始まるインデックスで各要素にアクセス
- サイズは作成時に決定され、後から変更できない
- 高速な要素アクセスが可能
配列を使うメリット:
配列を使わない場合、複数のデータを扱うには以下のように変数を個別に宣言する必要があります。
int age1 = 20;
int age2 = 25;
int age3 = 30;
int age4 = 35;
int age5 = 40;
配列を使えば、1つの変数で複数のデータを管理できます。
int[] ages = new int[5] { 20, 25, 30, 35, 40 };
基本的な配列の宣言と初期化
配列の宣言と初期化には、いくつかの方法があります。
方法1: サイズだけ指定して宣言
int[] numbers = new int[5];
この方法では、要素数が5個の配列が作成されます。各要素は、デフォルト値で初期化されます。
デフォルト値:
- 数値型(int, double など):
0 - bool型:
false - 参照型(string, object など):
null
方法2: 後から値を代入
int[] numbers = new int[3];
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
配列を作成した後、インデックスを指定して個別に値を代入できます。
方法3: 宣言と同時に値を指定
int[] numbers = new int[3] { 10, 20, 30 };
配列の宣言と同時に、波括弧{}の中に初期値を指定できます。
配列を一括で初期化する方法
配列を一括で初期化する方法はいくつかあります。それぞれ見ていきましょう。
標準的な一括初期化
完全な記法:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
配列の要素数は、初期値の個数から自動的に決まります。
要素数指定版:
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
要素数を明示的に指定することもできますが、初期値の個数と一致している必要があります。
簡略記法:
int[] numbers = { 1, 2, 3, 4, 5 };
new int[]を省略できます。これが最もシンプルな書き方です。
型推論を使った初期化
newと型推論:
var numbers = new[] { 1, 2, 3, 4, 5 };
new[]と書くと、コンパイラが初期値から型を自動的に推論してくれます。
文字列の例:
var fruits = new[] { "りんご", "バナナ", "オレンジ" };
初期値がすべて文字列なので、string[]型として推論されます。
C# 12のコレクション式(最新!)
C# 12から、さらに簡潔な書き方が追加されました。
int[] numbers = [1, 2, 3, 4, 5];
角括弧[]を使う新しい構文です。非常にシンプルで読みやすいのが特徴です。
様々な型での使用例:
string[] names = ["太郎", "花子", "次郎"];
double[] prices = [100.5, 200.0, 350.75];
bool[] flags = [true, false, true];
注意点:
コレクション式を使う場合、varは使えません。型を明示的に指定する必要があります。
// エラー! コレクション式では var を使えない
var numbers = [1, 2, 3, 4, 5]; // NG
// OK! 型を明示的に指定
int[] numbers = [1, 2, 3, 4, 5]; // OK
同じ値で配列を一括初期化する
配列のすべての要素を同じ値で初期化したい場合の方法を紹介します。
方法1: Array.Fill()を使う
int[] numbers = new int[5];
Array.Fill(numbers, 100);
// numbersの中身: [100, 100, 100, 100, 100]
Array.Fill()メソッドは、配列を指定した値で埋めてくれます。
完全なコード例:
using System;
class Program
{
static void Main()
{
// 5個の要素を持つ配列を作成
bool[] flags = new bool[5];
// すべての要素をtrueで埋める
Array.Fill(flags, true);
// 確認のため表示
foreach (var flag in flags)
{
Console.WriteLine(flag);
}
}
}
実行結果:
True
True
True
True
True
方法2: Enumerable.Repeat()を使う
using System.Linq;
int[] numbers = Enumerable.Repeat(100, 5).ToArray();
// numbersの中身: [100, 100, 100, 100, 100]
LINQ のEnumerable.Repeat()メソッドを使う方法です。
パラメータの順序:
- 第1引数: 繰り返す値
- 第2引数: 繰り返す回数
完全なコード例:
using System;
using System.Linq;
class Program
{
static void Main()
{
// 値10を7回繰り返す配列を作成
int[] numbers = Enumerable.Repeat(10, 7).ToArray();
// 確認のため表示
foreach (var num in numbers)
{
Console.Write(num + " ");
}
// 出力: 10 10 10 10 10 10 10
}
}
方法3: forループを使う
int[] numbers = new int[5];
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] = 100;
}
最もベーシックな方法です。細かい制御が必要な場合に便利です。
どの方法を使うべき?
Array.Fill()がおすすめの場合:
- シンプルに同じ値で埋めたいとき
- コードの意図が明確
Enumerable.Repeat()がおすすめの場合:
- LINQを使った処理と組み合わせるとき
- メソッドチェーンで処理したいとき
forループがおすすめの場合:
- 計算結果を代入したいとき
- インデックスに応じて異なる値を設定したいとき
連続した値で配列を初期化する
1, 2, 3…のような連続した値で配列を初期化する方法です。
Enumerable.Range()を使う
using System.Linq;
// 1から5までの連続した値
int[] numbers = Enumerable.Range(1, 5).ToArray();
// numbersの中身: [1, 2, 3, 4, 5]
パラメータの順序:
- 第1引数: 開始値
- 第2引数: 個数(終了値ではない!)
注意点:
第2引数は「終了値」ではなく「個数」です。
// 10から5個の連続した値
int[] numbers = Enumerable.Range(10, 5).ToArray();
// 結果: [10, 11, 12, 13, 14]
応用例: 計算式を適用する
using System.Linq;
// 2倍した値で初期化
int[] numbers = Enumerable.Range(1, 5)
.Select(x => x * 2)
.ToArray();
// 結果: [2, 4, 6, 8, 10]
// 0.1刻みの小数
float[] decimals = Enumerable.Range(1, 5)
.Select(x => x * 0.1f)
.ToArray();
// 結果: [0.1, 0.2, 0.3, 0.4, 0.5]
forループでの代替方法
int[] numbers = new int[5];
for (int i = 0; i < numbers.Length; i++)
{
numbers[i] = i + 1; // 1から始まる連続値
}
// 結果: [1, 2, 3, 4, 5]
多次元配列の初期化
C#では、2次元配列や3次元配列も扱えます。
2次元配列の初期化
基本的な書き方:
int[,] matrix = new int[2, 3];
2行3列の2次元配列を作成します。
値を指定して初期化:
int[,] matrix = new int[2, 3]
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
簡略記法:
int[,] matrix =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
要素へのアクセス:
int[,] matrix =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
Console.WriteLine(matrix[0, 0]); // 1
Console.WriteLine(matrix[0, 2]); // 3
Console.WriteLine(matrix[1, 1]); // 5
3次元配列の初期化
int[,,] cube = new int[2, 2, 2]
{
{
{ 1, 2 },
{ 3, 4 }
},
{
{ 5, 6 },
{ 7, 8 }
}
};
ジャグ配列(配列の配列)
// 宣言
int[][] jaggedArray = new int[3][];
// 各行を個別に初期化
jaggedArray[0] = new int[] { 1, 2, 3 };
jaggedArray[1] = new int[] { 4, 5 };
jaggedArray[2] = new int[] { 6, 7, 8, 9 };
一括初期化:
int[][] jaggedArray =
{
new int[] { 1, 2, 3 },
new int[] { 4, 5 },
new int[] { 6, 7, 8, 9 }
};
C# 12のコレクション式:
int[][] jaggedArray =
[
[1, 2, 3],
[4, 5],
[6, 7, 8, 9]
];
実践的な初期化の例
実際のプログラミングでよく使う初期化パターンを紹介します。
例1: 曜日の配列
string[] weekDays =
{
"月曜日",
"火曜日",
"水曜日",
"木曜日",
"金曜日",
"土曜日",
"日曜日"
};
C# 12版:
string[] weekDays =
[
"月曜日",
"火曜日",
"水曜日",
"木曜日",
"金曜日",
"土曜日",
"日曜日"
];
例2: 成績データ
int[] scores = { 85, 92, 78, 95, 88 };
// 平均を計算
double average = scores.Average();
Console.WriteLine($"平均点: {average}");
例3: 設定フラグ
bool[] features =
{
true, // 機能A: 有効
false, // 機能B: 無効
true, // 機能C: 有効
true // 機能D: 有効
};
例4: 九九の表
int[,] multiplicationTable = new int[9, 9];
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
multiplicationTable[i, j] = (i + 1) * (j + 1);
}
}
// 5 × 3 の結果を表示
Console.WriteLine(multiplicationTable[4, 2]); // 15
例5: ゲームのスコアボード
using System.Linq;
// プレイヤー5人のスコアを0で初期化
int[] playerScores = Enumerable.Repeat(0, 5).ToArray();
// スコアを更新
playerScores[0] = 100;
playerScores[1] = 85;
playerScores[2] = 120;
// 表示
for (int i = 0; i < playerScores.Length; i++)
{
Console.WriteLine($"プレイヤー{i + 1}: {playerScores[i]}点");
}
C# 12のスプレッド演算子
C# 12では、既存の配列を組み合わせて新しい配列を作る便利な機能が追加されました。
基本的な使い方
int[] array1 = [1, 2, 3];
int[] array2 = [4, 5, 6];
// 2つの配列を結合
int[] combined = [..array1, ..array2];
// 結果: [1, 2, 3, 4, 5, 6]
..がスプレッド演算子です。配列の要素を展開してくれます。
要素の追加と結合
int[] numbers = [1, 2, 3];
// 前後に要素を追加
int[] extended = [0, ..numbers, 4, 5];
// 結果: [0, 1, 2, 3, 4, 5]
実践例
string[] family = ["太郎", "花子"];
string[] friends = ["次郎", "三郎", "四郎"];
// 家族と友達を結合
string[] allPeople = [..family, ..friends];
// 結果: ["太郎", "花子", "次郎", "三郎", "四郎"]
// 自分を先頭に追加
string[] withMe = ["自分", ..allPeople];
// 結果: ["自分", "太郎", "花子", "次郎", "三郎", "四郎"]
よくあるエラーと対処法
配列の初期化でよく遭遇するエラーを紹介します。
エラー1: 要素数の不一致
// エラー!
int[] numbers = new int[3] { 1, 2, 3, 4, 5 };
エラーメッセージ:配列初期化子には、3 個の要素が必要です。
対処法:
要素数を省略するか、正しい個数を指定します。
// 解決策1: 要素数を省略
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
// 解決策2: 正しい要素数を指定
int[] numbers = new int[5] { 1, 2, 3, 4, 5 };
エラー2: varとコレクション式
// エラー!
var numbers = [1, 2, 3, 4, 5];
エラーメッセージ:コレクション式の対象型がありません
対処法:
型を明示的に指定します。
// 解決策
int[] numbers = [1, 2, 3, 4, 5];
エラー3: 型の不一致
// エラー!
int[] numbers = new int[] { 1, 2, "three", 4 };
エラーメッセージ:string から int へ暗黙的に変換できません
対処法:
すべて同じ型にするか、object型を使います。
// 解決策1: すべてintに統一
int[] numbers = new int[] { 1, 2, 3, 4 };
// 解決策2: object型を使う
object[] mixed = new object[] { 1, 2, "three", 4 };
エラー4: 範囲外アクセス
int[] numbers = new int[3];
numbers[3] = 10; // エラー!
エラーメッセージ:インデックスが配列の境界外です。
原因:
配列のインデックスは0から始まるため、要素数が3の配列は0, 1, 2までしかアクセスできません。
対処法:
int[] numbers = new int[3];
numbers[2] = 10; // OK! 最後の要素
配列のサイズを後から変更する
配列は作成後にサイズを変更できませんが、Array.Resize()を使うと新しい配列を作成できます。
Array.Resize()の使い方
int[] numbers = { 1, 2, 3 };
Console.WriteLine($"元のサイズ: {numbers.Length}"); // 3
// サイズを5に拡張
Array.Resize(ref numbers, 5);
Console.WriteLine($"拡張後: {numbers.Length}"); // 5
// 新しい要素に値を代入
numbers[3] = 4;
numbers[4] = 5;
// 確認
foreach (var num in numbers)
{
Console.Write(num + " ");
}
// 出力: 1 2 3 4 5
注意点:refキーワードが必要です。Array.Resize()は元の配列を置き換えるため、参照渡しになります。
サイズ縮小
int[] numbers = { 1, 2, 3, 4, 5 };
// サイズを3に縮小
Array.Resize(ref numbers, 3);
// 確認
foreach (var num in numbers)
{
Console.Write(num + " ");
}
// 出力: 1 2 3
Listとの使い分け
配列とよく似たものにList<T>があります。違いを理解しておきましょう。
配列(Array)の特徴
メリット:
- メモリ効率が良い
- アクセス速度が速い
- 構文がシンプル
デメリット:
- サイズが固定
- 要素の追加・削除が面倒
配列を使うべき場合:
- 要素数が最初から決まっている
- 頻繁に要素にアクセスする
- メモリ効率を重視する
Listの特徴
メリット:
- サイズを動的に変更できる
- 要素の追加・削除が簡単
- 便利なメソッドが豊富
デメリット:
- 配列より少しメモリを多く使う
- 内部的に配列を使っているため、拡張時にコストがかかる
Listを使うべき場合:
- 要素数が不明
- 頻繁に要素を追加・削除する
- コレクション操作のメソッドを使いたい
配列とListの変換
配列からList:
int[] numbers = { 1, 2, 3, 4, 5 };
List<int> list = new List<int>(numbers);
// または
List<int> list2 = numbers.ToList();
ListFrom配列:
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
int[] numbers = list.ToArray();
まとめ
C#の配列を一括で初期化する方法について解説しました。
重要なポイント:
- 配列の基本的な初期化は
new int[] { 1, 2, 3 } - 簡略記法は
int[] numbers = { 1, 2, 3 } - C# 12では
int[] numbers = [1, 2, 3]が使える - 同じ値で埋めるには
Array.Fill()が便利 - 連続値には
Enumerable.Range()を使う - 多次元配列は
int[,]で宣言 - スプレッド演算子
..で配列を結合できる Array.Resize()でサイズ変更(実際は新しい配列を作成)- 固定サイズなら配列、動的なら
List<T>
各初期化方法の使い分け:
// 最もシンプル
int[] numbers1 = { 1, 2, 3 };
// 型推論を使う
var numbers2 = new[] { 1, 2, 3 };
// C# 12(最新)
int[] numbers3 = [1, 2, 3];
// 同じ値で埋める
int[] numbers4 = Enumerable.Repeat(100, 5).ToArray();
Array.Fill(numbers4, 100);
// 連続値
int[] numbers5 = Enumerable.Range(1, 5).ToArray();
C#のバージョンや用途に応じて、適切な初期化方法を選びましょう。最新のC# 12が使える環境なら、コレクション式を使うと非常にシンプルで読みやすいコードが書けます!
参考情報:
- Microsoft公式ドキュメント: https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/arrays
- Collection Expressions: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-12.0/collection-expressions

コメント