Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果无法更改不可变的字符串变量,为什么可以更改它?_C# - Fatal编程技术网

C# 如果无法更改不可变的字符串变量,为什么可以更改它?

C# 如果无法更改不可变的字符串变量,为什么可以更改它?,c#,C#,这可能在其他地方被问到,但我只是在做一个简单的搜索时没有看到它。我正在学习C类,我知道字符串是不可变的,stringBuilder可以通过代码进行更改 但是如果字符串是不可变的,为什么C允许您更改它呢 或者,它允许您更改字符串,因为它占用了一个新的内存点,创建了另一个孔字符串变量,并放弃了另一个变量地址位置。如果是这种情况,并且自动垃圾收集完成并清理了C内存位置,那么使用string或stringBuilder真的很重要吗 代码: 这就是通过将变量指定给不同的值来改变变量的值 这不是改变变量所引

这可能在其他地方被问到,但我只是在做一个简单的搜索时没有看到它。我正在学习C类,我知道字符串是不可变的,stringBuilder可以通过代码进行更改

但是如果字符串是不可变的,为什么C允许您更改它呢

或者,它允许您更改字符串,因为它占用了一个新的内存点,创建了另一个孔字符串变量,并放弃了另一个变量地址位置。如果是这种情况,并且自动垃圾收集完成并清理了C内存位置,那么使用string或stringBuilder真的很重要吗

代码:


这就是通过将变量指定给不同的值来改变变量的值


这不是改变变量所引用的值。

这是通过将变量指定给不同的值来改变变量的值


这并不是改变变量所引用的值。

基本上你自己已经回答了这个问题。简而言之,C不允许您更改字符串

出于各种设计原因,c中的字符串被实现为一个字符串。您所做的是更改sss引用的内容,而不是更改被引用的内容。”abcd'与'ghy'分别存在与'nnnnnn'分别存在您不能将一件事更改为另一件事。您正在创建一个全新的东西,然后更改sss引用的内容

字符串在C中是不可变的,即使它们实现为。为什么?因为替代方案更糟糕:

考虑一个例子,其中字符串是引用类型,但不是不可变的,您可以将'abcd'更改为'ab12'。那看起来怎么样

string mutableString = "abcd";
string anotherRef = mutableString;

mutableString.mutateTo("ab12"); //A method that doesn't exist - for exposition only
在这一点上,另一个参考也将是ab12-这似乎非常不直观

关于

更多的是在特殊情况下使用的性能。对于大多数字符串连接,这并不重要。如果你有两个字符串,比如我的名字是和Pete,你把它们连在一起,然后你会得到一个新的字符串,我的名字是Pete,旧的字符串可能会被困在内存中的某个地方。没什么大不了的。您拥有所需的完整字符串-不会浪费很多时间或内存。考虑一个更极端的例子:如果你有更多的话:快速的棕色狐狸跳过懒狗,你想把它们连在一起:< /P> +quick生成一个新字符串 quick+brown生成quick brown另一个新字符串 快速棕色+狐狸产生快速棕色狐狸另一个新的字符串-越来越长 快速棕色狐狸+跳跃产生快速棕色狐狸跳跃另一个新的字符串-每一个比上一个更昂贵! 等 您可以看到,这个方法会产生很多您并不真正关心的额外中间字符串,但它们都会被分配—这需要时间—并且它们都会在内存中挂起,直到GC将其清除。StringBuilder为您提供了一种进行连接的方法,而无需分配每个中间结果


注意——下一部分严格来说不是真的,但对于这个例子来说已经足够接近了。StringBuilder的内部实现没有契约行为:您可以将其视为延迟连接。它可以在内部保存对所有组件字符串的引用,但在附加完字符串后调用ToString方法之前,不会为最终结果重新分配空间。这样,它就可以计算出所需的最终大小,并为整个组合字符串重新分配足够的空间—一次而不是n次。

您基本上已经自己回答了这个问题。简而言之,C不允许您更改字符串

出于各种设计原因,c中的字符串被实现为一个字符串。您所做的是更改sss引用的内容,而不是更改被引用的内容。”abcd'与'ghy'分别存在与'nnnnnn'分别存在您不能将一件事更改为另一件事。您正在创建一个全新的东西,然后更改sss引用的内容

字符串在C中是不可变的,即使它们实现为。为什么?因为替代方案更糟糕:

考虑一个例子,其中字符串是引用类型,但不是不可变的,您可以将'abcd'更改为'ab12'。那看起来怎么样

string mutableString = "abcd";
string anotherRef = mutableString;

mutableString.mutateTo("ab12"); //A method that doesn't exist - for exposition only
在这一点上,另一个参考也将是ab12-这似乎非常不直观

关于

更多的是在特殊情况下使用的性能。对于大多数字符串连接,这并不重要。如果你有两个字符串,比如我的名字是和Pete,你把它们连在一起,然后你会得到一个新的字符串,我的名字是Pete,旧的字符串可能会被困在内存中的某个地方。没什么大不了的。你有你想要的完整字符串-没有太多时间 内存被浪费了。考虑一个更极端的例子:如果你有更多的话:快速的棕色狐狸跳过懒狗,你想把它们连在一起:< /P> +quick生成一个新字符串 quick+brown生成quick brown另一个新字符串 快速棕色+狐狸产生快速棕色狐狸另一个新的字符串-越来越长 快速棕色狐狸+跳跃产生快速棕色狐狸跳跃另一个新的字符串-每一个比上一个更昂贵! 等 您可以看到,这个方法会产生很多您并不真正关心的额外中间字符串,但它们都会被分配—这需要时间—并且它们都会在内存中挂起,直到GC将其清除。StringBuilder为您提供了一种进行连接的方法,而无需分配每个中间结果


注意——下一部分严格来说不是真的,但对于这个例子来说已经足够接近了。StringBuilder的内部实现没有契约行为:您可以将其视为延迟连接。它可以在内部保存对所有组件字符串的引用,但在附加完字符串后调用ToString方法之前,不会为最终结果重新分配空间。这使它可以计算出所需的最终大小,并为整个组合字符串重新分配足够的空间-一次而不是n次。

请参见,看起来您当时回答了自己的问题。每次为字符串指定一个新值时,都会创建一个新对象,并最终收集旧对象。如果另一个字符串指向该旧字符串,则会发生什么情况,就像使用字符串b=棒球一样;和字符串d=b;如果您更改b='football',那么b将被垃圾收集,但是d是否在垃圾中被收集并返回到,或者它仍然指向b的内存位置?请参阅,看起来您已经回答了自己的问题。每次为字符串指定一个新值时,都会创建一个新对象,并最终收集旧对象。如果另一个字符串指向该旧字符串,则会发生什么情况,就像使用字符串b=棒球一样;和字符串d=b;如果您更改b='football',那么b将被垃圾收集,但是d是否在垃圾中被收集并返回到,或者它仍然指向b的内存位置?谢谢。如果您可以更改它们,那么您将更改对字符串的每个引用,所有内容都将更改,这就是为什么它们使它们不可变。如果您认为某个字符串必须在以后的程序中更改,我认为在某些情况下使用StringBuilder会更好。谢谢。如果您可以更改它们,那么您将更改对字符串的每个引用,所有内容都将更改,这就是为什么它们使它们不可变。我认为,如果您认为某个字符串必须在以后的程序中更改,那么在某些情况下使用StringBuilder会更好。