根据msdn的描述:
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
按照这样的说法,因为string类型是引用类型,拷贝的时候应该拷贝引用,而不是引用的对象,但是如下程序的输出顺序却是:
a b a
而不是:a b b
这是为什么啊
class test:ICloneable
{
string i;
public void Seti(string i)
{
this.i = i;
} public void Showi()
{
MessageBox.Show(i);
} public object Clone()
{
return this.MemberwiseClone();
}
} public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); test t1 = new test();
t1.Seti("a");
test t2 = (test)t1.Clone();
t2.Showi();
t1.Seti("b");
t1.Showi();
t2.Showi();
}
}
MemberwiseClone 方法创建一个浅表副本,方法是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。
按照这样的说法,因为string类型是引用类型,拷贝的时候应该拷贝引用,而不是引用的对象,但是如下程序的输出顺序却是:
a b a
而不是:a b b
这是为什么啊
class test:ICloneable
{
string i;
public void Seti(string i)
{
this.i = i;
} public void Showi()
{
MessageBox.Show(i);
} public object Clone()
{
return this.MemberwiseClone();
}
} public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); test t1 = new test();
t1.Seti("a");
test t2 = (test)t1.Clone();
t2.Showi();
t1.Seti("b");
t1.Showi();
t2.Showi();
}
}
之后确实如你所想
t2 t1指向同一个string "a"你的问题出在对这句的理解上
t1.Seti("b");
你觉的
public void Seti(string i)
{
this.i = i;
}
会将t1和t2所指向的同一个string修改了是吧实际不是这样,你这句话对t2没有任何影响,只是让t1.i指向了另一个string "b"
你只是理解了浅赋值,却忽略了引用类型的赋值不会更改人和对象,只会更改reference和instance的关联
对哦,明白了。
by the way ,如何修改string引用的对象,而不是改变引用和实例的关联呢?