仕事で久々にプログラミングに集中していたところ、
『値渡し』『参照渡し』という初歩的な事で躓きました。

DeepCopyで調べればいくつか実装方法は出てきたのですが、
現在参画している案件ではJSONを利用しているため、
JSONで解決することにしました。

コンソールアプリケーション版のサンプルを残しておきます。

環境
 .NET Framwork 4.6.1
 Newtonsoft.Json 12.0.1

余談~『JSON』とは~

いつも通り説明的なものは外部リンクに頼ります。

個人的には「どんなオブジェクトでも文字列として扱える」モノくらいに捉えています。

私がIT業界に入った頃の案件ではXMLで通信を行っていたりもしましたが、
2年ほど前からは通信で扱うのは全て『JSON』になりました。

今では通信データを全て『JSON』で扱おうと考えるぐらいに楽です。

『Newtonsoft.Json』のインストール

JSONを利用するにあたり、便利なパッケージを取得しておきます。

『ソリューションエクスプローラー』から作成したプロジェクトの
『参照』を右クリックします。

表示されたコンテキストメニューから
『Nugetパッケージの管理』をクリックします。

『参照』タブから「Newtonsoft.Json」を選択し、
右ペインの『インストール』ボタンをクリックします。

※右ペインでインストールするパッケージのバージョンを選択することが出来ますが、
 今回は最新版である「12.0.1」を使用します。

確認ダイアログが表示されたら『OK』をクリックします。

パッケージのインストールが完了するとプロジェクトの『参照』に
『Newtonsoft.Json』が追加されます。これでインストールは完了です。

余談~参照渡しとは~

また説明的なものは外部リンクに頼ります。

実際の話、どんなコードを書いたら遭遇するか、だけ書いておきます。

まず初めにクラスを定義します。

命名規則なんてものはいったん無視します!

次にMain関数に下記のコードを記述します。

上記のコードではDeepCopyクラスをインスタンス化(以下、オリジナルインスタンスとします)し、
さらにDeepCopyクラスの別インスタンス(以下、編集インスタンスとします)
にオリジナルインスタンスを与えています。

その後、編集インスタンスのプロパティの値を書き換え、最後にオリジナルインスタンスを表示します。

上記のコードを実行した結果がこちらになります。

オリジナルインスタンスのプロパティの値は書き換えていないのに、
表示された値は編集インスタンスで書き換えた値となりました。

これが『参照渡し』です。

DeepCopyの実現

『参照渡し』を体験したところで、いざ本題のDeepCopyです。

DeepCopyに関してはまたもや外部リンクに頼ります。

下記のメソッドを作成します。

引数として受け取ったクラスを一度JSON文字列に変換し、
JSON文字列からクラスに変換するだけのシンプルなコードです。

上記のメソッドを利用して下記のコードを作成しました。

上記コードではオリジナルインスタンスの書き換えが
行われていないことを確かめるために、
オリジナルインスタンスのプロパティに値を設定しています。

実行結果がこちら。

オリジナルインスタンスのプロパティの値が書き換えられないことを確認できました。

まとめ

  • 値が意図しないタイミングで書き換えられていたら『参照渡し』を疑う。
  • 『参照渡し』を解消するには変数の使い方を見直すか、DeepCopyの使用を検討する。
  • 『JSON』を利用することでDeepCopyをシンプルに実現できる。

「なぜ書き換わっている!?」という瞬間はいくらコードを見ても
気付かない場合が多いので焦ります…。

以上です。

スポンサーリンク