おーみんブログ

C#, ASP.NET Core, Unityが大好きです。

C#のMemberwiseCloneメソッドを用いてオブジェクトを複製する。

はじめに

C#のお勉強として出井秀行さんの『C# コードレシピ集』を読んでいたらオブジェクトを複製するMemberwiseCloneメソッドというものを知ったので備忘録として残しておきます。

サンプルコード

以下は値型のメンバーと参照型のメンバーを持つオブジェクトに対し、MemberwiseCloneメソッドを用いて複製を行うサンプルコードです。 オブジェクトがコピーされるのはもちろんですが、コピー後のメンバーがどうなるのかについても確認してみましょう。

public class Program
{
    static void Main()
    {
        var s1 = new Sample(1, new List<string> { "Test" });
        var s2 = s1.ShallowCopy();
        // コピーしたオブジェクトのメンバーの値を変更する。
        s2.Num = 2;
        s2.StrList[0] = "Test_Changed";
        Console.WriteLine($"{s1.Num},{s1.StrList[0]}");
        Console.WriteLine($"{s2.Num},{s2.StrList[0]}");
    }
}

public class Sample
{
    public int Num { get; set; }
    public List<string> StrList { get; set; }
    public Sample(int num, List<string> strList)
    {
        Num = num;
        StrList = strList;
    }
    // MemberwiseCloneメソッドはobject型で返却するのでSample型へキャストする必要があります。
    public Sample ShallowCopy() => (Sample)MemberwiseClone();
}
1,Test_Changed
2,Test_Changed

値型のメンバーはコピー前とコピー後で変更されていますが参照型のメンバーはどちらも変わっています。 MemberwiseCloneメソッドは参照先のアドレスをコピーしているだけなのでなるほど、参照先の値については同じなのですね。 参照型のメンバーも値型と同様の動きにしたい場合は(色々調べてみたのですが)どうやら一度MemberwiseCloneメソッドでオブジェクトのコピーを作成したのちに自前で実装していく必要がありそうでした。 その実装については以下の記事がとても分かりやすかったです!

qiita.com