我支持@docesam的答案和@Will Yu的部分答案。
这既不是浅拷贝也不是深拷贝,而是引用拷贝。-- docesam
ob2 = ob1; 这段代码创建了两个对象引用,它们都指向同一个对象。因此,通过 ob1 对对象所做的任何更改都将反映在后续使用 ob2 的操作中。--Will Yu
根据
MSDN(请参阅备注)的说法:
浅复制只复制数组的元素,无论它们是引用类型还是值类型,但不复制引用所指向的对象。新数组中的引用指向原始数组中引用指向的相同对象。
在这里我们有两点需要注意:
1.浅复制只复制元素。
2.浅复制保留元素的原始引用。
接下来,我将分别解释这两个问题。
首先,我们创建一个具有
Name
属性的
Person
类:
class Person
{
public string Name {get; set;}
}
然后在
Main()
方法中,我们创建一个
Person
数组。
var person1 = new Person(){ Name = "Jack" };
var person2 = new Person(){ Name = "Amy" };
var arrPerson = new Person[] { person1, person2 };
1. 浅拷贝会复制元素。
如果我们在浅拷贝中替换第一个元素,原始数组不应受影响。
var arrPersonClone = (Person[]) arrPerson.Clone();
arrPersonClone[0] = new Person(){Name = "Peter"};
Console.WriteLine( "After replacing the first element in the Shallow Copy" );
Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
结果:
The Original Array: Jack, Amy
The Shallow Copy: Peter, Amy
2. 浅复制保留元素的原始引用。
如果我们在浅复制中更改元素的属性,则原始数组将受到影响,因为该元素所引用的对象未被复制。
arrPersonClone = (Person[]) arrPerson.Clone();
arrPersonClone[0].Name = "Peter";
Console.WriteLine( "After changing the Name property of the first element in the Shallow Copy" );
Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
结果:
The Original Array: Peter, Amy
The Shallow Copy: Peter, Amy
那么一个简单的等号
=
是如何运作的呢?它会创建一个引用副本。对元素或被引用的对象进行的任何更改都将反映在原始数组和“复制”的数组中。
var arrPersonR = arrPerson;
arrPersonR[0].Name = "NameChanged";
arrPersonR[1] = new Person();
Console.WriteLine( "After changing the reference copy:" );
Console.WriteLine( $"The Original Array: , " );
Console.WriteLine( $"The Reference Copy: , " );
结果:
The Original Array: NameChanged, PersonChanged
The Reference Copy: NameChanged, PersonChanged
总之,
ob2 = ob1
不是浅拷贝,而是引用拷贝。
完整代码如下:
void Main()
{
var person1 = new Person(){ Name = "Jack" };
var person2 = new Person(){ Name = "Amy" };
var arrPerson = new Person[] { person1, person2 };
var arrPersonClone = (Person[]) arrPerson.Clone();
arrPersonClone[0] = new Person(){Name = "Peter"};
Console.WriteLine( "After replacing the first element in the Shallow Copy:" );
Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
Console.WriteLine( "\n" );
arrPersonClone = (Person[]) arrPerson.Clone();
arrPersonClone[0].Name = "Peter";
Console.WriteLine( "After changing the Name property of the first element in the Shallow Copy:" );
Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
Console.WriteLine( $"The Shallow Copy: {arrPersonClone[0].Name}, {arrPersonClone[1].Name}" );
Console.WriteLine( "\n" );
var arrPersonR = arrPerson;
arrPersonR[0].Name = "NameChanged";
arrPersonR[1] = new Person(){ Name = "PersonChanged" };
Console.WriteLine( "After changing the reference copy:" );
Console.WriteLine( $"The Original Array: {arrPerson[0].Name}, {arrPerson[1].Name}" );
Console.WriteLine( $"The Reference Copy: {arrPersonR[0].Name}, {arrPersonR[1].Name}" );
}
class Person
{
public string Name {get; set;}
}
obj1
进行任何复制操作... - Alexei LevenkovA ob2 = new A();
创建的对象几乎立即被丢弃。下一行将使ob2
成为与ob1
相同对象的引用,并且new A()
直到进行垃圾回收之前才会被清除。 - mpen