前回は、配列を代入でコピーしようとすると、コピー元とコピー先が連動してしまうという「誤ったコピー」を確認しました。今回はその解決策として、Array.Copyを使ったコピーの方法を見ていきます。
テスト用のボタンを作成する
まずはいつものように、フォームにボタンを1つ追加します。ボタンの表示は「Array.Copy」としておき、ダブルクリックしてクリックイベントを生成します。
図1 「誤ったコピー」の下に「Array.Copy」ボタンを追加
前回のおさらい:代入によるコピーの問題
前回のコードを振り返っておきます。haiAと同じ要素数のhaiBを用意し、haiB = haiA;と代入していました。
図2 前回の代入によるコピー(haiB = haiA)
リスト1 前回の誤ったコピー
//誤ったコピー
//参照代入問題
var haiA = new int[] { 10, 20, 30 };
var haiB = new int[haiA.Length];
haiB = haiA;
haiA[1] = 999;
//連動してhaiBの値も変わってしまう
このやり方では、haiAの値を変更すると、連動してhaiBの値も変わってしまうという問題がありました。代入しているのは配列の中身ではなく参照であるため、haiAとhaiBが同じ配列を指してしまうからです。今回はこれをArray.Copyで解決します。
コピー元とコピー先の配列を用意する
haiAとhaiBは前回と同じものを使うので、前回のコードからコピーしてきます。haiAは10、20、30の3要素を持つ配列、haiBはhaiA.Lengthを指定して同じ要素数で生成した配列です。
図3 button10_ClickにhaiAとhaiBの生成をコピー
リスト2 コピー元とコピー先の配列
//Array.Copy
var haiA = new int[] { 10, 20, 30 };
var haiB = new int[haiA.Length];
ここでのポイントは、haiBをnewで別の配列として生成している点です。Array.Copyはコピー先の配列を自動では作ってくれないので、受け皿となる配列をあらかじめ用意しておく必要があります。
Array.Copyの書き方
それではArray.Copyを書いていきます。Array.Copy(まで入力すると、引数の説明が表示されます。
図4 Array.Copyの引数(sourceArray, destinationArray, length)
引数は3つです。1つ目のsourceArrayにコピー元の配列、2つ目のdestinationArrayにコピー先の配列、最後のlengthに「何個コピーするか」を指定します。
リスト3 Array.Copyの引数
Array.Copy(sourceArray, destinationArray, length); //sourceArray : コピー元の配列 //destinationArray : コピー先の配列 //length : コピーする要素数
今回はコピー元がhaiA、コピー先がhaiBです。そして全件をコピーしたいので、3つ目の引数にはコピー元配列のLength、つまりhaiA.Lengthを指定します。これで全件コピーになります。
図5 3つ目の引数にhaiA.Lengthを指定
リスト4 Array.Copyで全件コピーする
//Array.Copy
var haiA = new int[] { 10, 20, 30 };
var haiB = new int[haiA.Length];
Array.Copy(haiA, haiB, haiA.Length);
件数を3のように直接書くこともできますが、haiA.Lengthとしておけば、コピー元の要素数が変わってもコードを修正する必要がありません。
コピー元を変更して動作を確認する
この状態でhaiAの値を変更したら、haiBがどうなるかを見てみます。前回と同じようにhaiA[1]に値を代入します。今回は888にしておきます。
リスト5 コピー後にhaiAの要素を変更する
Array.Copy(haiA, haiB, haiA.Length); haiA[1] = 888;
haiA[1] = 888;の行にブレークポイントを置いて実行し、「Array.Copy」ボタンをクリックします。
図6 haiA[1] = 888; の行にブレークポイントを置いて実行
ブレークポイントで止まったところでウォッチウィンドウを見ると、haiAもhaiBも10、20、30で同じ値になっています。Array.Copyによって、haiAの全要素がhaiBにコピーされていることがわかります。
図7 Array.Copy直後はhaiAもhaiBも10、20、30
ここでhaiA[1] = 888;の行を実行します。
図8 haiA[1]だけが888になり、haiB[1]は20のまま
haiAだけが、インデックス1の値(2番目の要素)が888になりました。haiBのほうは20のままです。つまり、前回のような参照の問題は起きていないということです。
まとめ
Array.Copyを使うと、haiAの値を変更してもhaiBは変化しません。代入の場合は2つの変数が同じ配列を参照していましたが、Array.Copyでは別々の配列に値だけがコピーされるからです。
図9 完成したコード
リスト6 今回の完成コード
private void button10_Click(object sender, EventArgs e)
{
//Array.Copy
var haiA = new int[] { 10, 20, 30 };
var haiB = new int[haiA.Length];
Array.Copy(haiA, haiB, haiA.Length);
haiA[1] = 888;
//haiAの値を変更してもhaiBは変化しない
}
配列をコピーしたいときは、代入ではなくArray.Copyを使うようにしてください。
■非公開コース「C#14新機能」プレゼント:
非公開コース「C#14新機能」(80分)をご覧になりたい方は
こちらからURLとパスワードを発行していますので、ご覧になってみてください。
非公開コース「C#14新機能」を観る
A01_はじめに
A02_プロジェクトの作成
B01_配列とは
B02_配列の生成とアクセス
B03_生成と同時に値を設定する
B04_型推論による生成
B05_メソッドの引数などにする場合の注意点
B06_Length
B07_IndexOfでの検索
B08_FindIndexでの検索
B09_Find
B10_Exists
B11_FindAllとFindLast
B12_誤ったコピー
B13_Array.Copy
B14_範囲指定のコピー
B15_Resize
C01_ArrayList
C02_List
C03_List 動的な要素の変更
C04_Listのコンストラクタ
C05_Listのコンストラクタ_Capacity
C06_ListTからArrayクラスのメソッドが呼ばれている
D01_コレクションインタフェースとは
D02_異なるコレクションクラスに互換性を持たせる
D03_インタフェースの階層構造
D04_クライアントができる操作を制限させる
D05_クライアントができる操作を制限させる_後半
D06_Enumerableの拡張メソッドに関して
D07_ReadOnly系のコレクションインタフェース
D08_AsReadOnly
D09_ToListでコピーする
D10_ListTはprivateで使う
■非公開コース「C#14新機能」プレゼント:
非公開コース「C#14新機能」(80分)をご覧になりたい方は
こちらからURLとパスワードを発行していますので、ご覧になってみてください。
非公開コース「C#14新機能」を観る





![図6 haiA[1] = 888; の行にブレークポイントを置いて実行](https://anderson02.com/wp-content/uploads/2026/10/collection-b13-fig06.jpg)

![図8 haiA[1]だけが888になり、haiB[1]は20のまま](https://anderson02.com/wp-content/uploads/2026/10/collection-b13-fig08.jpg)
