在C#中浅层复制内容时,字符串如何工作?

时间:2009-02-03 10:29:49

标签: c# .net shallow-copy

字符串被认为是引用类型,但可以像值一样。当浅层手动或使用MemberwiseClone()复制某些内容时,如何处理字符串?它们是否被分开并与副本和主人隔离?

4 个答案:

答案 0 :(得分:46)

字符串ARE引用类型。但是它们是不可变的(它们不能被更改),所以如果它们按值复制或通过引用复制它们并不重要。

如果它们被浅层复制,那么将复制引用...但是您无法更改它们,因此您不能同时影响两个对象。

答案 1 :(得分:24)

考虑一下:

public class Person
{
    string name;
    // Other stuff
}

如果你调用MemberwiseClone,你最终会得到两个单独的Person实例,但是它们的name变量虽然不同,但它们具有相同的值 - 它们将引用相同的字符串实例。这是因为它是一个浅层克隆。

如果更改其中一个实例中的名称,那么这不会影响另一个实例,因为这两个变量本身是分开的 - 您只是更改其中一个变量的值以引用不同的字符串。

答案 2 :(得分:6)

您只是复制引用(想想“指针”);这两个引用是分开的(但碰巧具有相同的值),但只有一个字符串对象。

答案 3 :(得分:0)

@stusmith有一个非常好的答案,乔恩(Jon)提到了浅表副本的行为。为了详细说明,我做了一个.NET Fiddle

您会注意到我制作了一个浅表副本,但实际上,因为唯一的成员是字符串,所以它也可以用作深表副本。需要明确的是,从对字符串的引用被复制的意义上说,它不是深度复制,因此,运行复制功能时,内存中存在两个引用相同字符串的对象。

对于许多应用程序来说,这很好,因为像我的示例一样,当我在复制第一个对象后更新字符串时,会创建一个新的字符串和引用,因此最终结果是两个对象的引用不同字符串值。

以下是小提琴正在做什么的预览:

// Create a person
Person a = new Person("Sally");

// Shallow copy the person
Person b = a.ShallowCopy();

// Change the name of the second person
b.firstName = "Bob";

// Observe that the original person's name has not changed
Console.WriteLine("First person is {0}", a.firstName);
Console.WriteLine("Second person is {0}", b.firstName);

// Output is:
// First person is Sally
// Second person is Bob