🫧

【C#】Cloneの使いどころがやっとわかった気がする話

に公開1

Cloneって何がいいの?

正直なところ、今まで既存で実装されているClone処理をなんとなーく使っていたため
なにが嬉しいのかが、イマイチ分かっていませんでした💦
ただ、最近実装していく中で「Cloneありがてえ~涙」となったことがあったので、記事にしたいと思います。

助かった例

助かったシチュエーションをそのまま書くとよろしくないので、あくまで例ですが

顧客情報が入ったインスタンスがあり、Excelに出力する必要があるとします。
その時、Excel出力時は不要だが、インスタンスとしては持っておきたいデータがあるとします。

失敗例😢

Cloneを使わないと

CustomerData original = new CustomerData
{
    Name = "佐藤花子",
    Address = "大阪府大阪市",
    Comment = "社内メモ:重要顧客、対応丁寧に!"
};

// Excel出力用に別変数に代入
CustomerData exportData = original;
// Commentは出力には不要なので削除
exportData.Comment = string.Empty; 
// Excel出力処理を実行!
OutputExcel(exportData);

// originalのデータを確認すると…
Console.WriteLine(original.Comment); // 元のデータのコメントも消されている?!

上記のように更新したくない元のデータが変わってしまっています!

解決策😊

Cloneを使うと…
まずCustomerDataクラスにClone処理を追加します。

public class CustomerData
{
    public string Name { get; set; }
    public string Address { get; set; }
    public string Comment { get; set; }

  // Clone処理
    public CustomerData Clone()
    {
        return new CustomerData
        {
            Name = this.Name,
            Address = this.Address,
            Comment = this.Comment
        };
    }
}

そしたら問題のソースに戻ります。

CustomerData original = new CustomerData
{
    Name = "佐藤花子",
    Address = "大阪府大阪市",
    Comment = "社内メモ:重要顧客、対応丁寧に!"
};

// 出力用に別インスタンスをクローン
CustomerData exportData = original.Clone();
// Commentは出力には不要なので削除
exportData.Comment = string.Empty;
// Excel出力処理を実行!
OutputExcel(exportData);

// originalのデータを確認すると…
Console.WriteLine(original.Comment); // 社内メモ:重要顧客、対応丁寧に! 元データ無事‼‼

元データを損なわずに実装できました!🎊

なぜこうなるのか?

これはC#のクラス(CustomerData)が 参照型 であるためです。

CustomerData exportData = original;

「新しいオブジェクトを作った」 ように見えて、
実際には同じインスタンス(オブジェクト)を2つの変数が参照しているだけです。

そのため、exportDataに対して行った変更が、そのままoriginalにも影響してしまいます。

Cloneの嬉しさ

Cloneを使えば、完全に別のインスタンスが生成されるため、以下のような処理が安全にできます

  • 元データを壊さずに加工・変換したい
  • Excel出力やAPI送信用に一時的に形を変えたい
  • 比較用に一時的に別の状態を作りたい

↑詳細はまた別の記事で書けたらと思います

まとめ

  • =で代入してもコピーにはならない!(参照がコピーされるだけ)
  • 元のデータを変更したくないときは、Cloneで別インスタンスを作ろう!

今までは「なんか付いてるから使う」レベルだったCloneですが、
それなりに意味を理解して使えるようになると、ありがたみを感じたという記事でした!

ラグザイア

Discussion