深层复制?浅层复制?何种情况用何种复制?
如何控制?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仍然是可以使用的?
}
}
}
如何控制?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仍然是可以使用的?
}
}
}
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仍然是可以使用的?
}关键在于理解引用自身的变化与它所引用的对象之间的变化的区别。
//创建一个对象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的
其实和 值类型一样的..只是复制了一个引用地址而已.
a1单独指向null,并没有改变a2的对象。结论是:
改变对象,所以指向这个对象的引用的值都会变化。
改变引用,并不能影响其它指向此对象的引用。
CA a2 = new CA(); // a2 指向一个新对象
a1.setCount(11111);
a2 = a1; // a2 指向 a1 对象,两者指向同一个对象
a2.setCount(22222); a1 = null; // a1 置为空,a2 还是原来指那个对象,并不影响
// 这里即使改为 a1 = new CA(),还是不影响 a2
6L原话:
a2 = a1; //a2指向 A1指向的对象1
a2 = a1;//a2指向的是a1的托管堆,
a2.setCount(22222);//这里调用的setCount是a1的方法,改变的当然也是a1的值
现在我大概明白了
可是新的疑问又出来了
C#中声明的都是引用吗?像CA a1,a2.它们仅仅是个引用而不代表真实的对象?真实的对象是new出来的?
那如果我想实现下面的运作可以吗CA a1 = new CA();
CA a2 = new CA();
a2 = a1;//我想不让a2这个引用指向a1所指向的对象,而是想让a2所指向的对象的内容被赋值为a1所指向的对象,该怎么做呢?
深拷贝与浅拷贝不同的是对于引用字段的处理,深拷贝将会在新对象中创建一个新的对象和
原始对象中对应字段相同的字段
Object类的MemberwiseClone 方法进行浅表复制。
public CA Clone()
{
return (CA)this.MemberwiseClone();
}
a1.setCount(11111);
a2 = a1.Clone();
a2.setCount(22222);
a2=a1
a2其实为a1的引用,而不是副本,它们指向同一个对象。
a2.SetValue(a1)
CA a1 = new CA();
CA a2 = a1.Clone(); // 可心这么做,但要自己实现 Clone() 方法,用于复制对象。
可能由于装箱机制的存在,感觉似乎是都以引用的形式存在,但他们的内存分派方式是不一样的,一个是栈,一个是堆。