3

由于字符串是 dotnet 中的 ref 类型,所以当我们更新变量 x时, y中也应该有更新?(因为它指的是 x 的值)。下面给出的示例程序,当 x 更新时 y 的值如何不改变?

public void assignment()
{
    string x= "hello";
    string y=x; // referencing x as string is ref type in .net
    x = x.Replace('h','j');
    Console.WriteLine(x); // gives "jello" output
    Console.WriteLine(y); // gives "hello" output 
}
4

3 回答 3

8

你是对的,最初,两者都x引用y同一个对象:

       +-----------+
y   -> |   hello   |
       +-----------+
            ^
x   --------+

现在看看这一行:

x = x.Replace('h','j');

会发生以下情况:

  1. x.Replace创建一个字符串(将 h 替换为 j)并返回对该新字符串的引用。

           +-----------+    +------------+
    y   -> |   hello   |    |   jello    |
           +-----------+    +------------+
                ^
    x   --------+
    
  2. 使用x = ...,您分配x给这个新的参考。y仍然引用旧字符串。

           +-----------+    +------------+
    y   -> |   hello   |    |   jello    |
           +-----------+    +------------+
                                  ^
    x   --------------------------+
    

那么如何就地修改字符串呢?你没有。C# 不支持就地修改字符串。字符串被刻意设计不可变的数据结构。对于可变的类似字符串的数据结构,请使用StringBuilder

var x = new System.Text.StringBuilder("hello");
var y = x;

// note that we did *not* write x = ..., we modified the value in-place
x.Replace('h','j');

// both print "jello"
Console.WriteLine(x);
Console.WriteLine(y);
于 2021-04-28T07:24:57.843 回答
3

这里已经有很好的答案为什么会发生这种情况。但是,如果您希望两者都打印“jello”,则可以使用ref关键字通过引用将 x 分配给 y。

string x = "hello";
ref string y = ref x;
x = x.Replace('h', 'j');
Console.WriteLine(x); // gives "jello" output
Console.WriteLine(y); // gives "jello" output 

更多关于 Ref locals的信息

于 2021-04-28T07:57:19.100 回答
1

返回的字符串是一个新的字符串引用。关于 string.Replace() MSDN 说:

“此方法不会修改当前实例的值。相反,它返回一个新字符串,其中所有出现的 oldValue 都替换为 newValue”

https://docs.microsoft.com/en-us/dotnet/api/system.string.replace?view=net-5.0

正如@Heinzi 所提到的 - 字符串是不可变的,对字符串执行的大多数操作都会产生新的字符串:

“字符串对象是不可变的:它们在创建后无法更改。所有看起来修改字符串的字符串方法和 C# 运算符实际上都在新的字符串对象中返回结果”

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#:~:text=String%20objects%20are%20immutable%3A%20they,in%20a%20new%20string% 20 对象

干杯!

于 2021-04-28T07:42:28.323 回答