看起来你可能会误认为浅拷贝和深拷贝之间的区别。
在浅拷贝中,将创建一个新对象,并且将复制原始成员的所有值。
ArrayList a = new ArrayList(); // Creates a reference variable and a new
// object and places a reference to it in a
ArrayList b = a; // Creates a new reference variable and copies the
// reference in a to b. They both refer to the same new ArrayList();
b = (ArrayList)a.Clone(); // Clone() creates a new object and copies the
// values from a into it, then assigns the reference to b.
// a and b now refer to different objects with the same values
当处理值类型和字符串不可变时,这一切都非常简单。当它开始与明显不同的是,当你开始处理参考类型的成员时。
不是像原来的文章那样分配字符串,而是创建一个简单的Person类,我们将通过该场景中发生的事情。
public class Person
{
public string Name { get; set; }
}
ArrayList a = new ArrayList(); // New object, reference in a
a.Add(new Person(){Name = "Jack"}); // New person object, reference added to a.
a.Add(new Person(){Name = "Jill"}); // New person object, reference added to a.
ArrayList b = (ArrayList)a.Clone(); // New ArrayList object created, references
// to both Person objects are copied to it,
// then the reference to the new ArrayList
// is stored in b.
此时,a和b都引用不同的ArrayList对象,它们引用了相同的Person对象。浅拷贝使得每个成员的值的副本,并且该值是对Person对象的引用,而不是对象本身。
正因为如此,一个Person对象所做的任何更改将反映在A和B:
Console.WriteLine(((Person)a[0]).Name); // Prints "Jack"
Console.WriteLine(((Person)b[0]).Name); // Prints "Jack"
((Person)a[0]).Name = "Not Jack"; // Changes the value of the object, which is
// referenced by both a and b.
Console.WriteLine(((Person)a[0]).Name); // Prints "Not Jack"
Console.WriteLine(((Person)b[0]).Name); // Prints "Not Jack"
这是一个浅拷贝的行为。
深度复制行为有点不同。当您在ArrayList上执行浅表复制时,它会创建一个新的ArrayList对象并复制原始值。当它是一个深层副本时,它将创建一个新的ArrayList对象,就像在浅拷贝中一样,但不是仅仅处理这些值,而是递归地对每个成员执行一个复制操作。
这里是在幕后进行了深刻的副本背后发生的事情一个简单的解释:
- 创建一个新的ArrayList对象。
- 浏览原始对象中的所有成员,并确定它是否为值类型或引用类型。
- 如果它是一个值的类型,它只是在价值
- 如果它是一个引用类型的副本,从第1步,但这种类型的开始。
一旦操作完成,您现在可以使a或b改变任何东西,而不影响其他ArrayList中的对象。
它不是深层复制,只有集合被克隆,而不是其元素。但是当你使用不可变的字符串时你看不到。克隆()具有如此不可预知性是List <>没有它的一个原因。 –
你不知道浅层和深层克隆意味着什么。你应该去看看他们。 – Will
@非常感谢!很有帮助。 – nicomp