请看下面的代码(摘自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

输出的最后两行我没有问题,但前两行告诉我objectA和objectB指向相同的内存块(因为在c#中,对象是引用类型)。

问题是如何使objectB成为objectA的副本,使它指向内存中的不同区域。我知道,尝试分配他们的成员可能无法工作,因为这些成员也可能是参考。我如何让对象b和对象a完全不同呢?


当前回答

关于这个已经有一个问题了,你们可以看看

深度克隆对象

例如,在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'。

其他回答

最简单的方法是在MyClass类中编写一个复制构造函数。

就像这样:

namespace Example
{
    class MyClass
    {
        public int val;

        public MyClass()
        {
        }

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

第二个构造函数只是接受自己类型的形参(您想要复制的形参),并创建一个具有相同值的新对象

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               

你可以这样做:

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

然后你就可以

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

注意:MemberwiseClone()创建当前System.Object的浅拷贝。

没有内置的方法。您可以让MyClass实现IClonable接口(但它有点不推荐使用),或者只是编写自己的复制/克隆方法。无论哪种情况,您都必须编写一些代码。

对于大对象,您可以考虑序列化+反序列化(通过MemoryStream),只是为了重用现有代码。

不管用什么方法,都要仔细思考“复制”到底是什么意思。它应该走多深,是否有Id字段除外等等。

关于这个已经有一个问题了,你们可以看看

深度克隆对象

例如,在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'。