【发布时间】:2011-04-16 19:32:00
【问题描述】:
我只是想确定一下:
string x = "";
char Char = x[0]; // throws exception: "Index was outside the bounds of the array"
这意味着字符串实际上被视为一个字符数组,对吗? (至少在内部。)
【问题讨论】:
我只是想确定一下:
string x = "";
char Char = x[0]; // throws exception: "Index was outside the bounds of the array"
这意味着字符串实际上被视为一个字符数组,对吗? (至少在内部。)
【问题讨论】:
C# 语言规范不保证字符串的内部表示。但是,它实现了索引运算符来为字符串中的每个字符提供一个字符。
编辑:为了澄清一些人已经评论过,是的,CLR 中 System.String 的内部表示是一个数组。但是,语言规范没有说明内部表示,所以这可能(但不太可能)改变。它说字符串必须作为字符序列工作。语言规范中关于这一点的唯一一点是在第 1.3 节中:
C# 中的字符和字符串处理使用 Unicode 编码。 char 类型代表一个 UTF-16 编码单元,string 类型代表一个 UTF-16 编码单元序列。
另外,MSDN 声明:
字符串是用于表示文本的 Unicode 字符的顺序集合。 String 对象是表示字符串的 System.Char 对象的顺序集合。 String 对象的值是顺序集合的内容,并且该值是不可变的(即只读)。
所以在这种情况下,我们现在讨论的是 CLR,而不是语言。 System.String -- 然而,即使在那里,他们也不保证数组,只保证顺序集合。
使用链表实现的字符串和在列表中向前移动n 空格的索引器将足以满足语言要求。 IList<char> 也可以满足要求,IList 不必是数组支持的。
【讨论】:
fixed (char* p = str) 增加 p 的事实表明,由数组支持的字符串是不成文的规则,也是当今的事实。
您可能会发现此MSDN doc 很有帮助。
简而言之,字符串“存储为 Char 对象的顺序只读集合”
而且,是的,它可以像 char 数组一样被访问。因此,如果 X 包含 String.Empty 以外的值,则 char Char=X[0;] 代码将返回字符串的第一个字符。
【讨论】:
据我所知,这是正确的。顺便说一句,这是一个带有everything you ever wanted to know about Strings的页面:
【讨论】:
每@JaredPar elsewhere on this site:
您创建的底层字符串将 还需要一个连续的内存块 因为它表示为一个数组 字符数(数组需要连续 记忆)。
我相信你不应该依赖它,因为它不是接口的一部分,但是如果这个语句是正确的,实现就是一个数组。鉴于我们对 char-strings 的了解以及 Microsoft 需要支持托管语言和本地语言之间的高效互操作,这对我来说是有意义的。
MSDN只说这个,不保证存储是数组。
字符串是一个顺序的集合 Unicode 字符用于 表示文本。 String 对象是一个 System.Char 的顺序集合 表示字符串的对象。这 String 对象的值是 顺序集合的内容, 并且该值是不可变的(即 它是只读的)。
【讨论】:
C# 只是一种语言。 string 关键字是 .Net 框架的 BCL 中 System.String 的别名。假设内部 String 是一个字符数组是非常安全的。来自 MSDN:
字符串是用于表示文本的 Unicode 字符的顺序集合。 String 对象是表示字符串的 System.Char 对象的顺序集合。
【讨论】:
这取决于你所说的“数组”是什么意思。
如果您指的是随机访问、固定长度、可整数索引的对象集合的一般计算概念,那么是的,可以将字符串视为完全一样。 (一般的计算概念通常包括在内存中连续,但除非在少数情况下,例如在不安全的代码中使用指针,否则这在 C# 方面意义不大。
如果你指的是这个概念的语言定义的 C# 实现,char[] 那么不是真的,两者是不同的东西。
在实践中,System.String 确实是作为 chars 的数组实现的,但不一定是这样。
语言吹毛求疵,实用一点:
如果您想对字符串执行与char[] 相同的操作,那么这通常会起作用(特别是,字符串是只读的)并且通常是最有效的方法,因为只要在概念上很简单。特别是,使用foreach 和使用在0 和str.Length - 1 之间移动的索引效果很好。类似地,可以对char[] 进行的很多操作都可以在string 上进行,例如CopyTo() 和强制转换为IEnumerable<char>。
如果你想真正拥有一个字符数组,那么你需要调用ToCharArray()。
【讨论】: