我赞同@docesam 的回答和@Will Yu 的部分回答。
这既不是浅拷贝也不是深拷贝,这是参考拷贝。 -- 文档
ob2 = ob1;此代码创建两个对象引用,它们都引用同一个对象。因此,通过 ob1 对对象所做的任何更改都会反映在 ob2 的后续使用中。 --于将
根据MSDN (see Remarks):
Array 的浅拷贝只复制 Array 的元素,无论它们是引用类型还是值类型,但它不会复制引用所引用的对象。新 Array 中的引用指向的对象与原 Array 中的引用指向的对象相同。
这里有两点需要注意:
- 浅拷贝复制元素。
- 浅拷贝保留元素的原始引用。
接下来,让我分别解释这两个。
首先,我们创建一个带有Name 属性的Person 类:
class Person
{
public string Name {get; set;}
}
然后在Main()方法中,我们创建一个Person数组。
// Create 2 Persons.
var person1 = new Person(){ Name = "Jack" };
var person2 = new Person(){ Name = "Amy" };
// Create a Person array.
var arrPerson = new Person[] { person1, person2 };
1.浅拷贝复制元素。
如果我们替换浅拷贝中的第一个元素,原数组应该不会受到影响:
// Create a shallow copy.
var arrPersonClone = (Person[]) arrPerson.Clone();
// Replace an element in the shallow copy.
arrPersonClone[0] = new Person(){Name = "Peter"};
// Display the contents of all arrays.
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。浅拷贝保留元素的原始引用。
如果我们在浅拷贝中更改元素的属性,原始数组将受到影响,因为该元素引用的对象没有被复制。
// Create a new shallow copy.
arrPersonClone = (Person[]) arrPerson.Clone();
// Change the name of the first person in the shallow copy.
arrPersonClone[0].Name = "Peter";
// Display the contents of all arrays.
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
那么简单的等号= 的行为如何?
它制作一个参考副本。对元素或引用对象的任何更改都将反映在原始数组和“复制”数组中。
// Create a reference copy.
var arrPersonR = arrPerson;
// Change the name of the first person.
arrPersonR[0].Name = "NameChanged";
// Replace the second person.
arrPersonR[1] = new Person(){ Name = "PersonChanged" };
// Display the contents of all arrays.
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}" );
结果:
The Original Array: NameChanged, PersonChanged
The Reference Copy: NameChanged, PersonChanged
总结,ob2 = ob1 不是浅拷贝,而是参考拷贝。
完整代码:
void Main()
{
// Create 2 Persons.
var person1 = new Person(){ Name = "Jack" };
var person2 = new Person(){ Name = "Amy" };
// Create a Person array.
var arrPerson = new Person[] { person1, person2 };
// ----------- 1. A shallow copy copies elements. -----------
// Create a shallow copy.
var arrPersonClone = (Person[]) arrPerson.Clone();
// Replace an element in the shallow copy.
arrPersonClone[0] = new Person(){Name = "Peter"};
// Display the contents of all arrays.
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" );
// ----------- 2. A shallow copy retains the original references of the elements. -----------
// Create a new shallow copy.
arrPersonClone = (Person[]) arrPerson.Clone();
// Change the name of the first person in the shallow copy.
arrPersonClone[0].Name = "Peter";
// Display the contents of all arrays.
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" );
// ----------- 2. The equal sign. -----------
// Create a reference copy.
var arrPersonR = arrPerson;
// Change the name of the first person.
arrPersonR[0].Name = "NameChanged";
// Replace the second person.
arrPersonR[1] = new Person(){ Name = "PersonChanged" };
// Display the contents of all arrays.
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;}
}