【C#】Cloneの使いどころがやっとわかった気がする話
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ですが、
それなりに意味を理解して使えるようになると、ありがたみを感じたという記事でした!

株式会社ラグザイア(luxiar.com)の技術広報ブログです。 ラグザイアはRuby on RailsとC#に特化した町田の受託開発企業です。フルリモートでの開発を積極的に推進しており、全国からの参加を可能にしています。柔軟な働き方で最新のソフトウェアソリューションを提供します。
Discussion
そういう時こそ record class を使うと Clone を実装しなくていいし、 with 式 で 特定プロパティを変更した新しいインスタンスが作ることができる し イミュータブルに使えるので便利です。