C#
 Computer >> コンピューター >  >> プログラミング >> C#

.NETでオブジェクトのディープコピー(深いコピー)を実行する方法

プログラミングにおいて、オブジェクトを複製する方法には「シャローコピー(浅いコピー)」と「ディープコピー(深いコピー)」の2種類があります。この記事では、.NET(C#)におけるディープコピーの基本概念と、実際のコード例を使った実装方法をわかりやすく解説します。

ディープコピーとは?

ディープコピーとは、オブジェクトの内容をすべて複製するコピー方式です。単に参照先のアドレスを共有するだけではなく、オブジェクトが内部的に保持している参照型のデータまで含めて、完全に独立した複製を作ります。

たとえば、コレクションのディープコピーを行う場合、元のコレクション内のすべての要素が複製された、まったく別の2つのコレクションが生成されます。そのため、片方のコレクションの要素を変更しても、もう片方には一切影響しません。

言い換えれば、オブジェクトが参照している先のオブジェクトも一緒にコピーされるのがディープコピーです。これにより、コピー元とコピー先が完全に分離され、互いの状態に干渉しなくなります。

ディープコピーのコード例

以下は、C#でディープコピーの動作を確認できるシンプルなサンプルコードです。新しいインスタンスを作成し、値型のフィールドを個別に代入することで、独立したコピーを実現しています。

class DeepCopy {
   public int a = 10;
}
class Program {
   static void Main() {
      // ディープコピー
      DeepCopy d = new DeepCopy();
      d.a = 10;
      DeepCopy d1 = new DeepCopy();
      d1.a = d.a;
      Console.WriteLine("{0} {1}", d1.a, d.a); // 10,10
      d1.a = 5;
      Console.WriteLine("{0} {1}", d1.a, d.a); //5,10
      Console.ReadLine();
   }
}

実行結果

10 10
5 10

実行結果の解説

まず、d1.a = d.a; の時点では両方とも 10 なので、「10 10」と表示されます。

次に d1.a = 5; としてコピー先の値を変更すると、出力は「5 10」になります。d1 の変更が d に影響していないことがポイントです。

これは、d1 が新しいインスタンスとして独立して作成され、フィールドの値のみをコピーしているためです。もしシャローコピーのように同じ参照を共有していた場合、d1.a を変更すると d.a も同時に変わってしまいます。

まとめ

  • ディープコピーは、オブジェクトとその参照先のデータをすべて複製する方式である
  • コピー元とコピー先は完全に独立しており、片方の変更がもう片方に波及しない
  • C#では、新しいインスタンスを作成して各メンバーを個別に代入するか、シリアライズやクローン処理などを利用して実装できる
  1. Excelでシートをコピーする方法|ドラッグ・右クリック・別ブックへの複製まで徹底解説

    ポイント 複製したいワークシートを選択し、Ctrlキーを押しながらシート見出しを目的の位置へドラッグ&ドロップすると、コピーが作成できます。 または、シート見出しを右クリックして「移動またはコピー」を選び、コピー先を指定する方法もあります。 別のExcelファイル(ブック)にコピーする場合は、両方のファイルを開いた状態で「表示」→「並べて表示」を使い、ドラッグ&ドロップでコピーします。 この記事では、Excelでシートをコピーするさまざまな方法をわかりやすく解説します。紹介する手順は、Excel 2019、Excel 2016、Excel 2013、Excel 2010、およびMicros

  2. 【Swift入門】DateComponentsとCalendarで日付オブジェクトを作成する2つの方法

    Swiftで日付(Date)オブジェクトを作成するには、DateComponents()を使用します。作成方法は大きく分けて2つあり、ここではシミュレータではなくPlaygroundを使ってコードを検証していきます。 日付の生成には「日付コンポーネント」と「カレンダー」を組み合わせます。まず、DateComponentsの作成方法を2つのパターンで見ていきましょう。 方法1:デフォルトのイニシャライザを使う 1つ目は、DateComponents()が持つデフォルトのイニシャライザに、必要な情報をまとめて渡す方法です。 var date = DateComponents.init(