中。网、串不可改变的,并参照类型的变量。这往往作为一个奇怪的新。网的开发者可能错误,他们为了价值的类型对象由于他们的行为。然而,其他实践的使用 StringBuilder 长级联esp。在循环中,没有任何理由在实践中,人们需要知道这个区别?

什么是真正的世界方案帮助或避免通过了解价值的参考区别有关。净串与只是假装/误解了他们要价值的类型?

有帮助吗?

解决方案

设计的 strings是故意这样的,你不需要担心的太多了关于它作为一个程序员。在许多情况下,这意味着你可以只分配、移动、复制、改变串没有想太多可能的错综复杂的后果,如果另一个参考你的串的存在,并将在相同时间发生变化(如发生对象的参考文献)。

串参数的方法的呼叫

(编辑:这一段后添加)
当串通过一种方法,他们通过参考。当他们只是读取的方法主体,没有什么特别的事情发生。但是当他们都变了,一个复制的创建和临时变量是用其他方法。这个过程被称为 复写.

什么烦恼的青少年是他们是用这样的事实,对象是参考文献和它们在方法改变传递的参数。这样做有弦,他们需要用的 ref 关键词。这实际上允许串的基准可改变的和返回给调功能。如果你不要,串不可改变的方法体:

void ChangeBad(string s)      { s = "hello world"; }
void ChangeGood(ref string s) { s = "hello world"; }

// in calling method:
string s1 = "hi";
ChangeBad(s1);       // s1 remains "hi" on return, this is often confusing
ChangeGood(ref s1);  // s1 changes to "hello world" on return

在StringBuilder

这种区别是重要的,但是初级程序员通常是最好不知道太多了。使用 StringBuilder 当你做了很多string"建筑"是不错,但通常,您的申请会有更多的鱼苗和小性能获得的 StringBuilder 是可以忽略不计。警惕的程序员,告诉你, 所有 串的操作应使用StringBuilder.

作为一个非常粗略的经验法则:StringBuilder有一些创造成本,但附加便宜。串了一个便宜的创造成本,但是连接是比较昂贵。 转折点是围绕400至500串联,根据尺寸:在这之后,StringBuilder变得更为有效。

更多关于StringBuilder vs串表现

编辑:根据评论康拉德*鲁道夫,我加入这个部分。

如果前一条经验法则让你知道,考虑以下更详细的解释:

  • StringBuilder有许多小型字符串的追加超过字符串连接而迅速(30日,追加50),但于2微,甚至100%的绩效益往往是可以忽略不计(安全的一些罕见的情况);
  • StringBuilder与一些大型字符串的追加(80字或大串)超过字符串连接只有在成千上万,有时候,百分之一的成千上万的迭代和差别通常只有几百分比;
  • 混合串行动(取代,插入,substring,regex等)经常使用StringBuilder或串联等;
  • 字符串连接的常量可以优化远编译器,CLR或JIT,它不能对StringBuilder;
  • 代码常常混合串联 +, StringBuilder.Append, String.Format, ToString 和其他串行动,使用StringBuilder在这种情况下是几乎没有有效的。

因此,当 这有效?在情况许多小型字符串所附的,即,序列数据的一个文件,例如,当你不需要改变"书面"一次数据"书面"要StringBuilder.和在情况许多方法需要追加的东西,因为StringBuilder是参照类型和串复制时,他们改变。

在被拘留的字符串

一个问题的上升不仅有初中程序员--当他们试图做的一个基准比较,并发现,有时结果是真实的,有时是假的,在看似相同的情况。发生了什么事?当串被拘留的编译器,并加入到全球静拘留池串,比较两个字符串之间可以指向同一个存储地址。当(参考!)比较两个平等字符串中,一个实习和一个不会产生错误的。使用 = 比较,或 Equals 不玩 ReferenceEquals 在处理串。

在串。空

在同一联盟适用一种奇怪的行为,有时在使用时发生 String.Empty:静 String.Empty 总是被拘留,但一个变量与分配的价值是没有的。然而,默认情况下编译器将分配 String.Empty 并指向同一个存储地址。结果是:一个可变的串的变量,当与 ReferenceEquals, 返回的真正,而同时,你可能期望的虚假代替。

// emptiness is treated differently:
string empty1 = String.Empty;
string empty2 = "";
string nonEmpty1 = "something";
string nonEmpty2 = "something";

// yields false (debug) true (release)
bool compareNonEmpty = object.ReferenceEquals(nonEmpty1, nonEmpty2);

// yields true (debug) false (release, depends on .NET version and how it's assigned)
bool compareEmpty = object.ReferenceEquals(empty1, empty2);

在深度

你基本上被问及什么情况下可能发生对新手来说。我想我的观点归结为避免 object.ReferenceEquals 因为它无法以可信的使用时用弦。其原因是串的实习时使用的字符串在不断代码,但不总是如此。你不能依靠这种行为。虽然 String.Empty"" 总是被拘留,这是不当的编译器,认为值是可改变的。不同的优化选择(试vs的释放和其他人)将产生不同的结果。

你需要的 ReferenceEquals 无论如何?与对象是有意义的,但是有弦它没有。教任何人工作与串以避免其使用情况,除非他们也明白 unsafe 和固定对象。

性能

时性是重要的,可以找出这一串是实际上 不可改变的, 使用 StringBuilder 总是最快的方法.

很多的信息,我在这里使用的是详细 在这个优秀的文字符串, 沿着与"如何"操纵串在地(可变strings)。

更新: 加入代码样本
更新: 添加'在深度'部分(希望有人找到这个有用的;)
更新: 加入了一些链接,增加部分上串params
更新: 加入估计为当从串stringbuilder
更新: 增加一个额外的部分,在StringBuilder vs串的性能,后一句话由康拉德*鲁道夫

其他提示

这是真正重要的大多数代码的唯一区别在于null可以分配给字符串变量的事实。

这是不可变类就像在所有常见的情况是值类型,你可以做相当多的编程并不多么在乎的区别。

当你挖得更深,在乎你有这种区分真正的使用性能很。例如,要知道,虽然传递字符串作为参数的方法,如果创建字符串的副本行为,复制实际上并没有发生。这可能是使用语言的人在那里实际上字符串是值类型意外(如VB6?),并通过大量的字符串作为参数,将不利于性能。

的字符串是一个特殊的品种。他们还没有被大多数程序员的值类型引用类型。通过使其不可变的,使用实习生池,它优化存储器使用,这将是巨大的,如果它是一个纯值类型。

更多读数这里:结果 C#.NET String对象真的是参照?在SO 结果 方法的String.intern MSDN上结果 串上(C#参考)MSDN

<强>更新结果 请参考abel的评论这一职务。它纠正了我误导性陈述。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top