C# 字符串底层实现

C# 字符串底层实现,c#,.net,string,C#,.net,String,我最近尝试在c中执行以下操作# 这是行不通的,因为str[i]显然只是一个get而不是一个set,所以我想知道string的底层实现是什么,它会迫使str[i]只成为get 它不只是char*的托管包装器吗?那么为什么我不能设置str[I]?你不能设置字符串的字符,因为.NETstring类是不可变的,这意味着它的内容在创建后不能更改。这样就可以多次安全地使用同一个字符串实例,而不用一个对象担心另一个对象会踩到它的字符串 如果您需要一个可变类,允许您操作字符串,请考虑使用 StringBuild

我最近尝试在c中执行以下操作#

这是行不通的,因为str[i]显然只是一个get而不是一个set,所以我想知道string的底层实现是什么,它会迫使str[i]只成为get


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

你不能设置字符串的字符,因为.NET
string
类是不可变的,这意味着它的内容在创建后不能更改。这样就可以多次安全地使用同一个字符串实例,而不用一个对象担心另一个对象会踩到它的字符串

如果您需要一个可变类,允许您操作字符串,请考虑使用<代码> StringBuilder < /代码>。< /P>


如果要与C进行比较,
String
类型类似于
constchar*
,只是不能丢弃constness
StringBuilder
更像是一个
char*
(自动调整分配大小)和一个方法(
ToString()
)从其内容创建一个新的、独立的
String
实例。

就像cdhowie回答的那样,它与c/c中的String概念不同++

如果您想了解以上内容,建议您可以尝试通过如下容器模拟实现

List<char> str = new List<char>("u r awesome");
str[0] = 'i';
str[2] = 'm';
Console.WriteLine(str.ToArray());
List str=新列表(“u r awesome”);
str[0]=“i”;
str[2]=‘m’;
Console.WriteLine(str.ToArray());

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

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

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

请注意这里的“基本”部分,但是BSTR本身也在中进行了解释


请注意,所有这些都应该被视为一个实现细节。尽管它不应该真正影响我们大多数人,但在调试互操作问题或一般理解过程中,它可能会有所帮助。

为此,最好使用
StringBuilder
,因为它的特定目的是允许构建字符串。完全同意。代码建议实际上只是试图说明,如果etk真的想通过索引操作元素,他是如何在另一个实现上实现的。
StringBuilder
正好允许这样做。:)相关:关于StringBuilder内部的详细信息这实际上是我想要的答案,特别是关于string是如何实现的,谢谢!
List<char> str = new List<char>("u r awesome");
str[0] = 'i';
str[2] = 'm';
Console.WriteLine(str.ToArray());