System.String底层实现

时间:2011-08-09 01:25:35

标签: c# .net string

我最近在c#

中尝试执行以下操作
string str = "u r awesome";
str[0]="i";

并且它不起作用,因为显然str [i]只是一个get而不是set,所以我想知道string的底层实现是什么会强制str [i]只是一个get。

它不仅仅是char *的托管包装器吗?那么为什么我不能设置str [i]?

3 个答案:

答案 0 :(得分:8)

您无法设置字符串的字符,因为.NET String类是 immutable - 这意味着在创建后无法更改其内容。这允许相同的字符串实例安全地使用多次,而没有一个对象担心另一个对象会踩到它的字符串。

如果您需要一个允许操作字符串的可变类,请考虑使用StringBuilder

如果你想与C比较,String类型就像const char *,除了你不能抛弃常量。 StringBuilder更像是char *(具有自动分配大小调整),并且使用方法(ToString())从其内容创建新的独立String实例。

答案 1 :(得分:5)

其他人提出的关于不变性的答案当然是正确的,并且是您遇到问题的“实际”原因。

由于您特别询问了底层实现(并且仅仅是出于好奇),并且作为对可能偶然发现此问题的其他人的参考,以下是来自Eric Lippert的有关该主题的更多信息:

  

“在.NET CLR中,字符串在内存中的布局几乎相同   在OLE自动化中实现BSTR的方式:作为单词对齐   内存缓冲区由一个四字节整数组成,给出长度   字符串,后跟两个字节的字符串字符   大块的UTF-16数据,后跟两个零字节。“

请注意这里的“几乎”部分,但是在Eric's blog中也解释了BSTR本身。

请注意,所有这些都应被视为实施细节。即使它不应该真正关注我们大多数人,但在调试互操作问题或一般理解时它可能会有所帮助。

答案 2 :(得分:2)

像cdhowie一样回答,它与c / c ++中的字符串概念不一样

如果您想要上述内容,作为建议您可以尝试通过容器模仿实现,如下面的

List<char> str = new List<char>("u r awesome");
str[0] = 'i';
str[2] = 'm';
Console.WriteLine(str.ToArray());