.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 替换。
简短版本:
不,它不应该指向同一个地址。它指向相同的地址,但您将 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"
。它不再引用旧对象 .
我有一个简单的 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 替换。
简短版本: 不,它不应该指向同一个地址。它指向相同的地址,但您将 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"
。它不再引用旧对象 .