- 2015/3/7 05:42
前回投稿した「浅いコピーと深いコピー」では、データクラスにディープコピーメソッドを実装しましたが、全てのデータクラスに深いコピーが必要なわけではありません。
汎用のディープコピーメソッドを作成しておくと、必要に応じてオブジェクトをコピーできるので便利です。
ディープコピーメソッドのソースコードは以下になります。
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace ShallowCopyTest
{
/// <summary>
/// コピーユーティリティ
/// </summary>
public static class CopyUtility
{
/// <summary>
/// 指定されたインスタンスの深いコピーを生成し返します
/// </summary>
/// <typeparam name="T">コピーするインスタンスの型</typeparam>
/// <param name="original">コピー元のインスタンス</param>
/// <returns>指定されたインスタンスの深いコピー</returns>
public static T DeepCopy<T>(T original)
{
// シリアル化した内容を保持するメモリーストリームを生成
MemoryStream stream = new MemoryStream();
try
{
// バイナリ形式でシリアライズするためのフォーマッターを生成
BinaryFormatter formatter = new BinaryFormatter();
// コピー元のインスタンスをシリアライズ
formatter.Serialize(stream, original);
// メモリーストリームの現在位置を先頭に設定
stream.Position = 0L;
// メモリーストリームの内容を逆シリアル化
return (T)formatter.Deserialize(stream);
}
finally
{
stream.Close();
}
}
}
}
それでは前回の会員クラス(Membership)をディープコピーしてみましょう。
// 会員1を生成
Membership membership1 = new Membership();
// 会員1のIDとパスワード、ニックネームを設定
membership1.ID = 1;
membership1.Password = "1234567890";
membership1.Nickname = "変数名.com";
// 会員2に会員1のディープコピーを代入
Membership membership2 =
CopyUtility.DeepCopy<Membership>(membership1);
// 会員1の情報を表示
Console.WriteLine("会員1 [{0}][{1}][{2}]",
membership1.ID, membership1.Password, membership1.Nickname);
// 会員2の情報を表示
Console.WriteLine("会員2 [{0}][{1}][{2}]",
membership2.ID, membership2.Password, membership2.Nickname);
Console.WriteLine();
// 会員1の情報を変更
membership1.ID = 999;
membership1.Password = "ABCDEFGHIJ";
membership1.Nickname = "リファクタ";
// 会員1の情報を表示
Console.WriteLine("会員1 [{0}][{1}][{2}]",
membership1.ID, membership1.Password, membership1.Nickname);
// 会員2の情報を表示
Console.WriteLine("会員2 [{0}][{1}][{2}]",
membership2.ID, membership2.Password, membership2.Nickname);
実行結果:
会員1 [1][1234567890][変数名.com]
会員2 [1][1234567890][変数名.com]
会員1 [999][ABCDEFGHIJ][リファクタ]
会員2 [1][1234567890][変数名.com]
無事に会員1の情報だけが変更されました。