我最近在c#
中尝试执行以下操作string str = "u r awesome";
str[0]="i";
并且它不起作用,因为显然str [i]只是一个get而不是set,所以我想知道string的底层实现是什么会强制str [i]只是一个get。
它不仅仅是char *的托管包装器吗?那么为什么我不能设置str [i]?
答案 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());