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

发布于 2024-07-13 11:57:10 字数 94 浏览 5 评论 0原文

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

Strings are considered reference types yet can act like values. When shallow copying something either manually or with the MemberwiseClone(), how are strings handled? Are they considred separate and isolated from the copy and master?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

荭秂 2024-07-20 11:57:10

字符串是引用类型。 然而它们是不可变的(它们不能被改变),所以它们是按值复制还是按引用复制并不重要。

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

Strings ARE reference types. However they are immutable (they cannot be changed), so it wouldn't really matter if they copied by value, or copied by reference.

If they are shallow-copied then the reference will be copied... but you can't change them so you can't affect two objects at once.

失去的东西太少 2024-07-20 11:57:10

考虑一下:

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

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

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

Consider this:

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

If you call MemberwiseClone, you'll end up with two separate instances of Person, but their name variables, while distinct, will have the same value - they'll refer to the same string instance. This is because it's a shallow clone.

If you change the name in one of those instances, that won't affect the other, because the two variables themselves are separate - you're just changing the value of one of them to refer to a different string.

戒ㄋ 2024-07-20 11:57:10

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

You are only copying a reference (think "pointer"); the two references are separate (but happen to have the same value), but there is only a single string object.

绳情 2024-07-20 11:57:10

@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

@stusmith has a really good answer, and jon mentions the behavior of a shallow copy. Just to elaborate on this I made a .NET Fiddle

You'll notice that I make a shallow copy, but really, since the only member is a string, is functions as a deep copy as well. To be clear, it IS NOT a deep copy in the sense that the reference to the string is duplicated, so when the copy function is ran, there exist two objects with references to the same string in memory.

However for many applications, this is fine because, like in my example, when I update the string after copying the first object, a new string and reference are created, and so the end result is two objects with different references to different string values.

Here is a preview of what the fiddle is doing:

// 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文