C#中的字符串引用[重复]
Posted
技术标签:
【中文标题】C#中的字符串引用[重复]【英文标题】:String reference in C# [duplicate] 【发布时间】:2021-07-21 12:51:36 【问题描述】:由于字符串是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
【问题讨论】:
不,基本上。改变一个变量的值(不影响其他变量)和改变一个对象的内容是有区别的。见jonskeet.uk/csharp/references.html 和***.com/a/32010236/22656 您在谈论可变与不可变。 String 是不可变的,它始终保持相同的值。字符串也是引用类型,它没有默认分配大小。 @Bizhan:这与不变性无关。即使字符串是可变的,改变一个变量的值也不会改变另一个变量。 (例如,假设我们使用StringBuilder
而不是string
,并且有问题的行是x = null;
- 这不会使y
为空。)
@JonSkeet 我认为它是也是关于不变性的,因为例如StringBuilder.Replace
发生变异并返回自身,所以x = x.Replace(...)
也会改变y
中的值。
@Charlieface:这正是我没有在我的示例中使用Replace
的原因。假设string
实际上是可变的,但Replace
的当前行为是返回一个新字符串而不是修改现有字符串。 (例如,也许会有一个 ReplaceInExistingObject
方法会改变它。)这个问题中的行为根本不会改变。
【参考方案1】:
您是对的,最初,x
和 y
都引用同一个对象:
+-----------+
y -> | hello |
+-----------+
^
x --------+
现在看看这一行:
x = x.Replace('h','j');
会发生以下情况:
x.Replace
创建一个 new 字符串(将 h 替换为 j)并返回对这个新字符串的引用。
+-----------+ +------------+
y -> | hello | | jello |
+-----------+ +------------+
^
x --------+
使用x = ...
,您可以将x
分配给这个新引用。 y
仍然引用旧字符串。
+-----------+ +------------+
y -> | hello | | jello |
+-----------+ +------------+
^
x --------------------------+
那么如何就地修改字符串?你没有。 C# 不支持就地修改字符串。字符串是deliberately designed 作为一个不可变 数据结构。对于可变的类似字符串的数据结构,使用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);
【讨论】:
【参考方案2】:这里已经有很好的答案为什么会发生这种情况。
但是,如果您希望两者都打印“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
更多关于参考本地人here的信息。
【讨论】:
非常好,虽然我个人更喜欢称它为“让 y 成为 x 的别名”,以避免短语“通过引用分配”的歧义。跨度> 【参考方案3】:返回的字符串是一个新的字符串引用。 关于 string.Replace() MSDN 说:
"此方法不会修改当前实例的值,而是返回一个新字符串,其中所有出现的 oldValue 都替换为 newValue"
https://docs.microsoft.com/en-us/dotnet/api/system.string.replace?view=net-5.0.
正如@Heinzi 所述 - 字符串是不可变的,对字符串执行的大多数操作都会产生新字符串:
“字符串对象是不可变的:它们在创建后无法更改。所有看似修改字符串的 String 方法和 C# 运算符实际上都在新的字符串对象中返回结果”
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#:~:text=String%20objects%20are%20immutable%3A%20they,in%20a%20new%20string%20object.
干杯!
【讨论】:
以上是关于C#中的字符串引用[重复]的主要内容,如果未能解决你的问题,请参考以下文章
无论c#中的字符是啥,如何根据每三个字符分割一个字符串[重复]