C#中string是不可变的疑问

sinat_22417511 2017-09-21 05:34:42
在许多书和资料中都有说string是不可变的,修改的都是基于副本的修改。那么有个问题
 class Program
{
static void Main(string[] args)
{
string str1 = "ni";
string str2 = "hello";
str1 += str2;

Console.WriteLine(str1);

}


str1用自身和str2连接了,那么这种情况,str1是否还是不可变,具体的原理是什么?
...全文
612 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuzuning 2017-09-25
  • 打赏
  • 举报
回复
string是不可变的 是说,对字符串的任何改变,都将产生一个副本(虽然你可以将这个副本重新赋予原字符串变量)
闭包客 2017-09-25
  • 打赏
  • 举报
回复
引用 11 楼 dongmusic 的回复:
[quote=引用 10 楼 closurer 的回复:] 这里要提一下,C#、Java 中 string 的 imutable,是指实例的不可变,并不是变量的不可变,你的 str1 赋值之后,还是可以被重复赋值的,只是每次赋值都会产生新的实例。 在一些语言中,比如 F#,变量默认就是 imutable 的,初始化之后就不能被重复赋值。 所以变量的 imutable 和实例的 imutable 是两个不同的概念。
看的有点糊涂,其它人的解释还算明白,你这样一解释就又乱了。[/quote] 我只是看你代码的思路,好像就是理解成变量的 imutable 了。你可以了解一下 C# 的 readonly 关键字。
dongmusic 2017-09-24
  • 打赏
  • 举报
回复
引用 10 楼 closurer 的回复:
这里要提一下,C#、Java 中 string 的 imutable,是指实例的不可变,并不是变量的不可变,你的 str1 赋值之后,还是可以被重复赋值的,只是每次赋值都会产生新的实例。 在一些语言中,比如 F#,变量默认就是 imutable 的,初始化之后就不能被重复赋值。 所以变量的 imutable 和实例的 imutable 是两个不同的概念。
看的有点糊涂,其它人的解释还算明白,你这样一解释就又乱了。
MYsce 2017-09-24
  • 打赏
  • 举报
回复
是不可变创建了一个临时的,然后保存
threenewbee 2017-09-22
  • 打赏
  • 举报
回复
str1 += str2; -> str1 = st1 + str2; 先创建一个临时的,保存str1+str2 然后引用传给str1 还是只读的
闭包客 2017-09-22
  • 打赏
  • 举报
回复
这里要提一下,C#、Java 中 string 的 imutable,是指实例的不可变,并不是变量的不可变,你的 str1 赋值之后,还是可以被重复赋值的,只是每次赋值都会产生新的实例。 在一些语言中,比如 F#,变量默认就是 imutable 的,初始化之后就不能被重复赋值。 所以变量的 imutable 和实例的 imutable 是两个不同的概念。
SpringHgui 2017-09-21
  • 打赏
  • 举报
回复

string str1 = "ni";
string str2 = "hello";
str1 += str2;
可以这么理解

string str1 = "ni";
string str2 = "hello";

string newStr = str1 + str2; // 底层新开辟了一个string对象newStr 
str1 = newStr ; // 引用的地址改变了
sinat_22417511 2017-09-21
  • 打赏
  • 举报
回复
引用 1 楼 hanjun0612 的回复:
都是不可变的, 字符串的所有操作,都是新的字符串。 str1 += str2 只是又新开了一个str1,实际上 str1="ni" 和第二个 str1=str1+str2 已经不是一个了。 而老的str1会被回收掉。
谢谢解答
  • 打赏
  • 举报
回复
str1指向了一个新的地址,这个地址就是str1+str2字符串的地址,原来的str1处于未命中状态,gc回收时原来的str1就会被释放
真相重于对错 2017-09-21
  • 打赏
  • 举报
回复
用stringbuilder
正怒月神 2017-09-21
  • 打赏
  • 举报
回复
引用 4 楼 closurer 的回复:
虽然你的样子没变,但是你已经不是从前的你了。
说的很有内涵。
闭包客 2017-09-21
  • 打赏
  • 举报
回复
虽然你的样子没变,但是你已经不是从前的你了。
正怒月神 2017-09-21
  • 打赏
  • 举报
回复
这也就涉及到,频繁的操作字符串,推荐使用stringbuilder而不是使用string。 因为string每次操作都会开新空间来存储。
正怒月神 2017-09-21
  • 打赏
  • 举报
回复
都是不可变的, 字符串的所有操作,都是新的字符串。 str1 += str2 只是又新开了一个str1,实际上 str1="ni" 和第二个 str1=str1+str2 已经不是一个了。 而老的str1会被回收掉。

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧