我只是学习C#并使用一些字符串和StringBuilder的例子。从我的阅读中,我明白如果我这样做:
string greeting = "Hello";
greeting += " my good friends";
我得到一个名为greeting的新字符串,其中包含连接值。我知道运行时(或编译器,或其他)实际上已经摆脱了对原始字符串问候语的引用,并用一个同名的新连接替换它。
我只是想知道这有什么实际应用/衍生物。为什么对我来说,当对我的影响仅仅是我的初始变量改变了值时,C#如何在背景中改变字符串是很重要的。
我想知道是否有人可以给我一个程序员需要知道差异的场景。 *一个简单的例子会很好,因为我是相对初学者。
提前致谢..
答案 0 :(得分:4)
string greeting = "Hello Foo!";
greeting.Replace("Foo", "World");
而不是正确的:
string greeting = "Hello Foo!";
greeting = greeting.Replace("Foo", "World");
除非你知道字符串是一个不可变的类,否则你可能会怀疑第一种方法是合适的。
为什么对我来说,当对我的影响仅仅是我的初始变量改变了值时,C#如何在背景中改变字符串很重要。
另一个具有巨大优势的主要地方是引入并发时。在并发情况下,不可变类型更容易处理,因为您不必担心另一个线程是否在同一引用中修改相同的值。使用不可变类型通常可以避免潜在的同步成本(即:锁定)。
答案 1 :(得分:1)
据我所知,运行时(或编译器或其他)实际上已经摆脱了对原始字符串问候语的引用,并将其替换为同名的新连接符号。
Pedantic intro:No。对象没有名字 - 变量有。它将新对象存储在同一个变量中。因此,用于访问对象的名称(变量)是相同的,即使它(变量)现在引用另一个对象。对象也可以存储在多个变量中,并且同时具有多个“名称”,或者任何变量都不能直接访问它。
对于字符串的情况,问题的其他部分已经简洁地回答了 - 但是,可变/不可变的分支要大得多。以下是一些可能会在背景下扩大问题范围的问题。
通常,必须知道并正确遵守对象的合同(API和使用模式/范围/限制),以确保程序的有效性。我通常发现不可变对象使生活更容易(因为只有一个上述“问题” - 只有25% - 甚至适用)。
快乐的编码。
答案 2 :(得分:1)
C#没有任何“洗牌”,你是!您的语句为变量分配了一个新值,引用的对象本身没有改变,您只是删除了引用。
不变性有用的主要原因是:
String greeting = "Hello";
// who knows what foo does
foo(greeting);
// always prints "Hello" since String is immutable
System.Console.WriteLine(greeting);
您可以共享对不可变对象的引用,而不必担心其他代码更改对象 - 它不会发生。因此,不可变对象更容易推理。
答案 3 :(得分:0)
大多数时候,影响很小。然而,在连接许多字符串的情况下,收集所有这些字符串的垃圾的性能损失变得有问题。用一个字符串做太多的字符串操作,你的应用程序的性能可能会急剧下降。
这就是为什么StringBuilder在你需要进行大量字符串操作时更有效的原因;将所有那些'孤立'字符串留在那里对垃圾收集器造成的问题不仅仅是修改内存缓冲区。
答案 4 :(得分:0)
我认为不可变字符串的主要好处在于使内存管理更容易。
C#为每个对象逐字节分配内存。如果创建字符串“Tom”,则占用三个字节。然后,您可以分配一个整数,即四个字节。如果您随后尝试将字符串“Tom”更改为“Tomas”,则需要移动所有其他内存以为两个新字符a和s腾出空间。
为了消除这种痛苦,为字符串“Tomas”分配五个新字节会更容易(也更快)。
这有帮助吗?
答案 5 :(得分:0)
在性能方面,immutuable的优点是复制对象在CPU和内存方面都很便宜,因为它只涉及制作指针的副本。缺点是写入对象变得更加昂贵,因为它必须在过程中复制对象。