String是一种引用类型,尽管它具有值类型的大多数特征,例如不可变和重载==以比较文本,而不是确保它们引用同一个对象。
为什么字符串不只是一个值类型呢?
String是一种引用类型,尽管它具有值类型的大多数特征,例如不可变和重载==以比较文本,而不是确保它们引用同一个对象。
为什么字符串不只是一个值类型呢?
当前回答
这主要是性能问题。
在编写代码时,让字符串的行为像值类型一样有帮助,但如果它是值类型,则会对性能造成巨大影响。
要深入了解,请参阅一篇关于.net框架中字符串的好文章。
其他回答
字符串是具有值语义的引用类型。这种设计是一种折衷,允许某些性能优化。
The distinction between reference types and value types are basically a performance tradeoff in the design of the language. Reference types have some overhead on construction and destruction and garbage collection, because they are created on the heap. Value types on the other hand have overhead on assignments and method calls (if the data size is larger than a pointer), because the whole object is copied in memory rather than just a pointer. Because strings can be (and typically are) much larger than the size of a pointer, they are designed as reference types. Furthermore the size of a value type must be known at compile time, which is not always the case for strings.
但是字符串有值语义,这意味着它们是不可变的,并通过值(即字符串的字符逐个字符)进行比较,而不是通过比较引用。这允许某些优化:
实习意味着如果已知多个字符串相等,编译器可以只使用一个字符串,从而节省内存。这种优化只在字符串不可变的情况下有效,否则更改一个字符串将对其他字符串产生不可预测的结果。
字符串字面值(在编译时已知)可以被编译器存储在内存的一个特殊静态区域中。这节省了运行时的时间,因为它们不需要分配和垃圾收集。
不可变字符串确实会增加某些操作的成本。例如,您不能就地替换单个字符,必须为任何更改分配一个新字符串。但与优化的好处相比,这是一个很小的成本。
值语义有效地为用户隐藏了引用类型和值类型之间的区别。如果一个类型具有值语义,那么该类型是值类型还是引用类型对用户来说并不重要——它可以被视为一个实现细节。
简单地说,任何具有一定大小的值都可以被视为值类型。
它不是一个值类型,因为如果它是一个值类型,并且它的值每次传递给方法或从方法返回时都必须复制,那么性能(空间和时间!)会很糟糕。
它有价值语义来保持世界的理智。你能想象编码有多困难吗
string s = "hello";
string t = "hello";
bool b = (s == t);
设b为假?想象一下编写任何应用程序是多么困难。
实际上,字符串与值类型几乎没有相似之处。对于初学者来说,并不是所有的值类型都是不可变的,你可以随心所欲地改变Int32的值,而它在堆栈上的地址仍然是相同的。
字符串是不可变的有一个很好的理由,这与它是引用类型无关,但与内存管理有很大关系。当字符串大小发生变化时,创建一个新对象比在托管堆上移动对象更有效。我认为你把值/引用类型和不可变对象的概念混在一起了。
至于“==”:就像你说的,“==”是一个操作符重载,它的实现有一个很好的理由,使框架在处理字符串时更有用。
此外,字符串的实现方式(每个平台都不同)以及何时开始将它们拼接在一起。就像使用StringBuilder一样。它为你分配了一个缓冲区供你复制,一旦你到达终点,它会为你分配更多的内存,希望如果你做一个大的连接性能不会受到阻碍。
也许乔恩·斯基特可以过来帮忙?