208

以下のコードを見てください (C# の本からの抜粋):

public class MyClass 
{
    public int val;
}
public struct myStruct 
{
    public int val;
}
public class Program 
{
    private static void Main(string[] args) 
    {
        MyClass objectA = new MyClass();
        MyClass objectB = objectA;

        objectA.val = 10;
        objectB.val = 20;

        myStruct structA = new myStruct();
        myStruct structB = structA;

        structA.val = 30;
        structB.val = 40;

        Console.WriteLine("objectA.val = {0}", objectA.val);
        Console.WriteLine("objectB.val = {0}", objectB.val);
        Console.WriteLine("structA.val = {0}", structA.val);
        Console.WriteLine("structB.val = {0}", structB.val);

        Console.ReadKey();
    }
}

以下の出力が生成されることを理解しています。

objectA.val = 20
objectB.val = 20
structA.val = 30
structB.val = 40

出力の最後の 2 行は問題ありませんが、最初の 2 行はobjectAobjectBが同じメモリ ブロックを指していることを示しています (C# ではオブジェクトは参照型であるため)。

問題は、メモリ内の別の領域を指すようobjectBに のコピーを作成する方法です。objectAそれらのメンバーも参照である可能性があるため、メンバーを割り当てようとするとうまくいかない場合があることを理解しています。objectBでは、 とはまったく異なるエンティティを作成するにはどうすればよいobjectAでしょうか?

4

4 に答える 4

173

あなたがすることができます:

class myClass : ICloneable
{
    public String test;
    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

それからあなたはすることができます

myClass a = new myClass();
myClass b = (myClass)a.Clone();

NBMemberwiseClone()現在の System.Object の浅いコピーを作成します。

于 2011-07-04T09:30:12.963 に答える
135

組み込みの方法はありません。MyClass にインターフェースを実装させることもIClonable(ただし、非推奨のようです)、独自の Copy/Clone メソッドを作成することもできます。どちらの場合でも、いくつかのコードを記述する必要があります。

大きなオブジェクトの場合、既存のコードを再利用するためだけに、シリアライゼーション + デシリアライゼーション (MemoryStream を介して) を検討できます。

どのような方法であれ、「コピー」とは正確には何を意味するのかをよく考えてください。どのくらい深くする必要がありますか、除外する Id フィールドはありますか?

于 2011-07-04T09:25:07.290 に答える
55

これを行う最も簡単な方法は、MyClass クラスにコピー コンストラクターを記述することです。

このようなもの:

namespace Example
{
    class MyClass
    {
        public int val;

        public MyClass()
        {
        }

        public MyClass(MyClass other)
        {
            val = other.val;
        }
    }
}

2 番目のコンストラクターは、独自の型 (コピーする型) のパラメーターを単純に受け入れ、同じ値が割り当てられた新しいオブジェクトを作成します。

class Program
{
    static void Main(string[] args)
    {
        MyClass objectA = new MyClass();
        MyClass objectB = new MyClass(objectA);
        objectA.val = 10;
        objectB.val = 20;
        Console.WriteLine("objectA.val = {0}", objectA.val);
        Console.WriteLine("objectB.val = {0}", objectB.val);
        Console.ReadKey();
    }
}

出力:

objectA.val = 10

objectB.val = 20               
于 2011-07-04T09:48:37.343 に答える
12

これについてはすでに質問があります。おそらくそれを読むことができます

オブジェクトのディープ クローニング

たとえば Java に存在する Clone() メソッドはありませんが、クラスにコピー コンストラクターを含めることができます。これは別の優れたアプローチです。

class A
{
  private int attr

  public int Attr
  {
     get { return attr; }
     set { attr = value }
  }

  public A()
  {
  }

  public A(A p)
  {
     this.attr = p.Attr;
  }  
}

これは、新しいオブジェクトを構築するときにメンバー「Attr」をコピーする例です。

于 2011-07-04T09:26:54.683 に答える