.NET C# 中的字符串操作

String Manipulation in .NET C#

我有一个简单的 C# 概念性问题。 在 C# 中,字符串是引用类型。所以这意味着当我创建一个字符串变量 'ABC' 时,它将只包含对托管堆上实际字符数组的引用或地址。

所以,如果我写:

string ABC = "Hye";
String XYZ = ABC;
ABC = ABC.Replace("H","B");

Console.WriteLine("ABC - "+ ABC);
Console.WriteLine("XYZ - "+ XYZ);

实际输出为:

 ABC - Bye
 XYZ - Hye

但我预计在这两种情况下都是再见,因为我认为 XYZ 也将指向与 ABC 相同的地址,并且 ABC 中的任何更改都将反映在 XYZ 中。

谁能告诉我哪里错了?

我认为这一行:

ABC = ABC.Replace("H","B");

创建字符串的新实例。来自 MSDN: 该方法不修改当前实例的值。相反,它 returns 一个新字符串,其中所有出现的 oldValue 都被 newValue 替换。

Info - MSDN

简短版本: 不,它不应该指向同一个地址。它指向相同的地址,但您将 ABC 中的地址替换为另一个地址(替换的结果)。

长版

这样想 - 赋值运算符 (=) 以及将参数传递给方法和从方法中 returning 值总是进行复制。引用类型和值类型之间的区别在于复制的是什么。当值是一个值类型时,内存中的整个数据被复制到内存中的另一个地方。变量本身包含数据。使用引用类型时,变量(以及方法参数和方法 return 值)保存对象在内存中的地址。这就是为什么当您将一个变量分配给另一个变量时,它们指向同一个对象。两个变量存储相同的地址。但是 = 运算符仍然执行从一个变量到另一个变量的复制。它复制地址。因此,当您从替换方法分配 return 值时,您将新字符串的地址复制到变量 ABC 中。您不会在其他变量中复制任何内容。他们曾经指向同一个对象,但现在他们不指向同一个对象,因为在 ABC 中复制的地址现在不同了。引用类型的变量不是通过某种魔法链接的,它们是通过它们持有同一对象的地址这一事实来链接的,但地址本身只是数字。如果在变量上使用 = 运算符,则替换对象。如果更改对象,两个变量中的值都会更改,但如果替换对象,变量将包含不同的对象。

请注意,这也适用于方法参数。

List<string> list = new List<String> { "asdf" };
SomeMethod(list);
//list contains "asdf", "fdsa"
SoemOtherMethod(list),
//list is NOT null

static void SomeMethod(List<string> list)
{
    list.Add("fdsa"); //changes the original list
}

static void SomeOtherMethod(List<string> list)
{
    list = null; //cannot replace the original list only replaces the address in the argument variable
}

让我们逐行查看您的代码;

string ABC = "Hye";

通过这一行,您创建了字符串对象 "Hye" 和对该对象的引用 ABC.

String XYZ = ABC;

通过这一行,您创建了一个名为 XYZ 的引用,该引用引用了与 ABC 引用相同的对象,即 "Hye"

ABC = ABC.Replace("H","B");

因为字符串 immutable types, String.Replace() method 不会改变原始对象。它 returns 一个 new 对象和你的 ABC 引用引用那个对象 "Bye"。它不再引用旧对象 .