じゃんぬのどっとてきすと

雑記とネタと時々プログラミング

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  981  : 記事  4  : コメント  23021  : トラックバック  277

ニュース

My Website

初心者向けのサイトです。

C# と VB.NET の入門サイト

最近のできごと

少し前に女のコが生まれました。家事と育児と仕事にと奮起しています。めちゃくちゃかわいいです。あと Blog の更新は全然してませんが、Twitter とかでアホなこと呟いています。見つけることができたら、ぜひフォローしてあげてください。けっこう喜びます。

Sponsored Link1

Sponsored Link2

Archive

書庫

前回の ICloneable と MemberwiseClone からの続きです。
シャローコピー (Shallow Copy) と、ディープコピー (Deep Copy) について書きます。

前回の記事で、System.Object.MemberwiseClone メソッドでクローン コピーする場合、
参照型のメンバについては、参照先のインスタンスそのものがコピーされるのではなく、
参照先を示すアドレスがコピーされるだけであるということを書きました。
つまり、コピー元もコピー先も結局は同じものを指し示していることを意味します。

このようなクローン コピーを、シャローコピー (Shallow Copy、簡易コピー、浅いコピーなど) と言います。
逆に、参照先のインスタンスをも複製する場合は、ディープコピー (Deep Copy、深いコピーなど) と言います。

こうやって書くと、シャローコピーが (「簡易コピー」という名称なので) 劣っているかのように見えますが、
シャローコピーを使うか、ディープコピーを使うかは臨機応変であり、劣っているわけではありません。

次に、MemberwiseClone メソッドを使ったシャローコピーと、ディープコピーの例を示します。
前回と同様、System.ICloneable インターフェイスを実装して、複製できることを明示します。

VB.NET

Option Strict On

' テスト用のデータクラス (System.ICloneable インターフェイスを実装)
Public Class WankumaMember : Implements System.ICloneable

    ' 面倒なのでフィールド メンバにしちゃってます
    Public MemberCode As Integer
    Public MemberName As String
    Public Age        As Integer
    Public Skills     As New System.Collections.ArrayList() '参照型
    Public Version    As New System.Version()               '参照型

    ' シャローコピー (Shallow Copy)
    Public Function ShallowCopy() As WankumaMember
        Return DirectCast(Me.Clone(), WankumaMember)
    End Function

    ' ディープコピー (Deep Copy)
    Public Function DeepCopy() As WankumaMember
        ' まずは簡易コピーしたものを格納
        Dim hWankuma As WankumaMember = DirectCast(Me.Clone(), WankumaMember)

        ' 参照型のメンバをクローン コピーする
        hWankuma.Skills  = DirectCast(Me.Skills.Clone(),  System.Collections.ArrayList)
        hWankuma.Version = DirectCast(Me.Version.Clone(), System.Version)

        Return hWankuma
    End Function

    ' System.ICloneable.Clone メソッド (非公開メンバとする)
    Private Function Clone() As Object Implements System.ICloneable.Clone
        Return Me.MemberwiseClone()
    End Function

End Class

シャローコピー側はそのままの実装で、MemberwiseClone メソッドの戻り値を同クラスの型に変換しているだけです。
ディープコピーについては、一旦簡易コピーした後に、参照型のメンバ (Skills、Version) をクローン コピーしています。

このようにオブジェクトのコピーは、手動によるコピーと、シャローコピー、ディープコピーがあります。
まあ、コレクションやデータクラスでないと普通は使わないとは思いますが、臨機応変に使い分けてください。

投稿日時 : 2006年4月7日 9:38

コメント

# re: シャローコピー と ディープコピー 2008/01/30 16:36 通りがかりの人
C#で下記のように記述したら、コンパイルエラー
// System.ICloneable.Clone メソッド (非公開メンバとする)
private object Clone()
{
return this.MemberwiseClone();
}

当たり前だけど、なぜVB.NETは通るだ?!

# re: シャローコピー と ディープコピー 2008/03/07 10:33 リック
MemberwiseClone が用意されているので、シャローコピーを実装する手間が省けていいですね(^-^)
Java にも追加されないかな?


# シャローコピー と ディープコピー 2013/11/02 11:38
上の二人って両方 バ カ だよな

Post Feedback

タイトル
名前
Url:
コメント: