C#中字符串的内部表示方式

5

我只是想确认一下:

string x = "";   
char Char = x[0];  // throws exception: "Index was outside the bounds of the array"

这意味着字符串实际上被视为字符数组,对吗?(至少在内部是这样的。)
6个回答

13
C#语言规范不保证字符串的内部表示。但是,它实现了索引运算符,为字符串中的每个字符提供一个char。请注意,语言规范并未说明内部表示,因此这可能会更改。它说字符串必须作为char序列工作。MSDN指出,字符串是用于表示文本的Unicode字符的连续集合。String对象是表示字符串的System.Char对象的连续集合。所以在这种情况下,我们现在谈论的是CLR而不是语言。System.String--但即使在那里,他们也不保证数组,只保证连续集合。使用链接列表实现字符串,并且索引器在列表中向前移动n个空间将足以满足语言要求。IList也将满足要求,而IList不必支持数组。

7
“序列集合”不等同于“数组”。我认为你应该撤回你的负评。 - Steve Townsend
1
在规范性 ECMA 文档中唯一的限制是关于字符缓冲区,而不是特定的 System.Array 实例:System.String 的实现必须包含一个可变长度的字符缓冲区,位于字符串对象开头固定数量的字节之后。 - Julien Roncaglia
2
是否为数组并不是问题 - 显然它是一个数组。问题是它是否必须是一个数组,我在文档中没有看到任何说明。 - David Pfeffer
1
@Steve 我没有看到问题被限制在托管代码的任何地方。事实上,这个问题涉及到内部表示,可能超出了托管代码的范围。 - Bear Monkey
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Drew Noakes
显示剩余8条评论

6
根据 @JaredPar 在 本站其他地方 的说法:
创建的基础字符串也需要一个连续的内存块,因为它被表示为字符数组(数组需要连续的内存)。
我确定您不应该依赖此作为接口的一部分,但是如果此语句正确,则实现是一个数组。就 char-strings 和 Microsoft 支持管理和本机语言之间的高效互操作所知,这对我来说是有道理的。 MSDN 只是说了这个,它并不保证存储是一个数组。
一个字符串是一个用于表示文本的 Unicode 字符的顺序集合。String 对象是表示字符串的 System.Char 对象的顺序集合。String 对象的值是顺序集合的内容,并且该值是不可变的(即只读)。

1

你可能会发现这个MSDN文档有帮助。

简而言之,字符串是“作为Char对象的顺序只读集合存储的”

是的,它可以像char数组一样访问。因此,如果X包含除String.Empty以外的值,则char Char=X[0];代码将返回字符串的第一个字符。


1

1

C#只是一种编程语言。在 .Net 框架的 BCL 中,字符串关键字是 System.String 的别名。可以非常安全地假设,在内部 String 是一个字符数组。来自 MSDN 的描述:

字符串是用于表示文本的 Unicode 字符序列。String 对象是表示字符串的 System.Char 对象的顺序集合。


0

这取决于你所说的“数组”的含义。

如果你指的是一般计算概念中的随机访问、固定长度、整数可索引对象集合,那么字符串可以被认为是完全像那样的。 (一般计算概念通常包括在内存中连续,但除了在不安全代码中使用指针等少数情况外,在C#方面并没有太多意义)。

如果你指的是语言定义的C#实现这个概念,char[],那么实际上两者是不同的东西。

实际上,System.String确实被实现为一个char数组,但它不一定非得这样。

除了语言细节之外,实际应用:

如果您想对字符串执行与char[]相同的操作,则通常可以使用此方法(尤其是,字符串是只读的),并且往往是最有效的方法,只要概念上非常简单。特别是,使用foreach和使用在0str.Length - 1之间移动的索引效果很好。同样,许多可以在char[]上执行的操作也可以在string上执行,例如CopyTo()和强制转换为IEnumerable<char>
如果您确实需要一个字符数组,则需要调用ToCharArray()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接