深层复制?浅层复制?何种情况用何种复制?
如何控制?using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
    public class CA
    {
        private int m_iCount;
        
        public void setCount(int iT)
        {
            m_iCount = iT;
        }        public int getCount()
        {
            return m_iCount;
        }
    }    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }        private void button1_Click(object sender, EventArgs e)
        {
            CA a1 = new CA();
            CA a2 = new CA();
            
            a1.setCount(11111);
            a2 = a1;
            a2.setCount(22222);            MessageBox.Show(a1.getCount().ToString());//为什么a1的也变成了22222?如果不想让a1也变该怎么办?
            MessageBox.Show(a2.getCount().ToString());            a1 = null;
            MessageBox.Show(a2.getCount().ToString());//如果前面表示a2就是a1了的话,为什么这里a2仍然是可以使用的?
        }
    }
}

解决方案 »

  1.   


            private void button1_Click(object sender, EventArgs e)
            {
                CA a1 = new CA();
                CA a2 = new CA();
                
                a1.setCount(11111);
                a2 = a1;//这里只是引用的复制,即a1这个引用自身而非它引用的对象复制到a2。
                a2.setCount(22222);//此时a1与a2引用同一个对象            MessageBox.Show(a1.getCount().ToString());//为什么a1的也变成了22222?如果不想让a1也变该怎么办?
                MessageBox.Show(a2.getCount().ToString());//这个是当然的了,本来就是同一个对象嘛            a1 = null;//现在a1不引用任何对象,但a2并不影响。
                MessageBox.Show(a2.getCount().ToString());//如果前面表示a2就是a1了的话,为什么这里a2仍然是可以使用的?
            }关键在于理解引用自身的变化与它所引用的对象之间的变化的区别。
      

  2.   

     CA a1 = new CA();
    //创建一个对象CA a1指向对象CA 暂时使用地址 1表示把
                CA a2 = new CA();
    //创建一个对象CA a2指向对象CA 暂时使用地址 2表示把            a1.setCount(11111);     //改变1的数据
                a2 = a1;            //a2指向 A1指向的对象1
                a2.setCount(22222);  //改变2的数据            MessageBox.Show(a1.getCount().ToString());//为什么a1的也变成了22222?如果不想让a1也变该怎么办?  这个输出的确实是 对象1的值    
                MessageBox.Show(a2.getCount().ToString());      //还是对象1的值            a1 = null;   //a1指向空  不是对象为空 ...
                MessageBox.Show(a2.getCount().ToString());//如果前面表示a2就是a1了的话,为什么这里a2仍然是可以使用的       //a2还是指向1的
    其实和 值类型一样的..只是复制了一个引用地址而已.
      

  3.   

    a2=a1,把a1,a2指向了同一个对象,当a2修改的时候,对象改变了,所以 a1的取值也变了。
    a1单独指向null,并没有改变a2的对象。结论是:
    改变对象,所以指向这个对象的引用的值都会变化。
    改变引用,并不能影响其它指向此对象的引用。
      

  4.   

                CA a1 = new CA();   // a1 指向一个新对象
                CA a2 = new CA();   // a2 指向一个新对象
                
                a1.setCount(11111);
                a2 = a1;            // a2 指向 a1 对象,两者指向同一个对象
                a2.setCount(22222);            a1 = null;          // a1 置为空,a2 还是原来指那个对象,并不影响
                                         // 这里即使改为 a1 = new CA(),还是不影响 a2
      

  5.   

    为什么6L说的又是对象?
    6L原话:
    a2 = a1; //a2指向 A1指向的对象1 
      

  6.   

    这跟深层或者浅层复制没有什么关系啊,这是有关引用类型的 a1.setCount(11111);//
     a2 = a1;//a2指向的是a1的托管堆,
     a2.setCount(22222);//这里调用的setCount是a1的方法,改变的当然也是a1的值
      

  7.   

    非常感谢大家的帮助
    现在我大概明白了
    可是新的疑问又出来了
    C#中声明的都是引用吗?像CA a1,a2.它们仅仅是个引用而不代表真实的对象?真实的对象是new出来的?
    那如果我想实现下面的运作可以吗CA a1 = new CA();
    CA a2 = new CA();
    a2 = a1;//我想不让a2这个引用指向a1所指向的对象,而是想让a2所指向的对象的内容被赋值为a1所指向的对象,该怎么做呢?
      

  8.   

    浅拷贝是指将对象中的所有字段逐字复制到一个新对象
    深拷贝与浅拷贝不同的是对于引用字段的处理,深拷贝将会在新对象中创建一个新的对象和
    原始对象中对应字段相同的字段
    Object类的MemberwiseClone 方法进行浅表复制。
    public CA Clone()
            {
                return (CA)this.MemberwiseClone();
            }
     a1.setCount(11111);
     a2 = a1.Clone();
     a2.setCount(22222);
    a2=a1
    a2其实为a1的引用,而不是副本,它们指向同一个对象。
      

  9.   

    写一个函数赋值
    a2.SetValue(a1)
      

  10.   

    C# 的语言设计便是 OOP 式的,是引用加堆内存……像 Class c1 = new Class ();这种 c1 是一个引用变量。引用可以赋给 null,但并不等同于 C++ 里面的指针指空。Class c2 = c1; 是引用传递。这是 C# 规定的。若要 c2 获得与 c1 指向的对像不是同一个,却是和 c1 所指的对像一模一样的对像,其实就是想获得 c1 所指对像的“副本”,使用克隆重载方法。Class c2 = c1.Clone();这里 c1 与 c2 都不是对像本身,而是对像的引用,对像本身呢?在堆内存,在后台,受 GC 管理,你自己摸不到。这与 C++ 是很不同的。
      

  11.   

    这个需要在CA这个类中实现深复制,虽然类都有一个从Object继承来的Clone方法,不过这个默认实现是浅复制,可以重写这个方法,使用MemberwiseClone,另外,如果CA中某成员是引用类型的话,也需要这个引用类型实现深复制。
      

  12.   


    CA a1 = new CA();
    CA a2 = a1.Clone(); // 可心这么做,但要自己实现 Clone() 方法,用于复制对象。
      

  13.   

    你现在在.Net版的等级只能发最高100分的帖子。
      

  14.   

    只说一部分。c#中的类型分为值类型(简单类型(int,long等)、结构类型、枚举),引用类型(Class、string、数组、接口,Delegate)。
    可能由于装箱机制的存在,感觉似乎是都以引用的形式存在,但他们的内存分派方式是不一样的,一个是栈,一个是堆。