首页 文章

在C#中创建对象的副本[重复]

提问于
浏览
128

可能重复:如何在.Net(特别是C#)中深层复制对象?

请看下面的代码(摘自C#书):

namespace Example {
    class MyClass {
        public int val;
    }

    struct myStruct {
        public int val;
    }

    class Program {
        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

输出的最后两行我没有问题,但前两行告诉我 objectAobjectB 指向同一个内存块(因为在C#中,对象是引用类型) .

问题是如何使 objectBobjectA 的副本,以便它指向内存中的不同区域 . 我理解,尝试分配他们的成员可能不起作用,因为这些成员也可能是参考 . 那么如何让 objectBobjectA 完全不同呢?

谢谢

4 回答

  • 7

    没有内置方式 . 你可以让MyClass实现 IClonable 接口(但它有点被弃用)或只是编写你自己的Copy / Clone方法 . 在任何一种情况下,您都必须编写一些代码 .

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

    无论采用何种方法,都要仔细考虑“副本”的含义 . 它应该有多深,是否有被禁止的Id字段等 .

  • 115

    你可以这样做:

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

    那么你可以做到

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

    注: MemberwiseClone() 创建当前System.Object的浅表副本 .

  • 40

    最简单的方法是在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
    
  • 88

    关于这个问题已经有了问题,你也许可以阅读它

    Deep cloning objects

    例如,Java中不存在Clone()方法,但您可以在clases中包含复制构造函数,这是另一种好方法 .

    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' .

相关问题