【问题标题】:Internal representation of strings in C#C#中字符串的内部表示
【发布时间】:2011-04-16 19:32:00
【问题描述】:

我只是想确定一下:

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

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

【问题讨论】:

    标签: c# string char


    【解决方案1】:

    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 不必是数组支持的。

    【讨论】:

    • @Bear Monkey - “顺序收集”与“数组”不同。我认为你应该收回你的反对票。
    • 规范性 ECMA 文档中关于字符缓冲区的唯一限制,而不是具体的 System.Array 实例:System.String 的实现需要包含一个固定字节数的可变长度字符缓冲区在 String 对象的开头之后。
    • 它是否是一个数组不是问题——显然它是一个数组。问题是它是否必须是一个数组,我在文档中的任何地方都没有看到任何说明。
    • @Steve 我在任何地方都看不到问题仅限于托管代码。事实上,这个问题是关于内部表示的,可能不仅仅是托管代码。
    • C# 语言允许 fixed (char* p = str) 增加 p 的事实表明,由数组支持的字符串是不成文的规则,也是当今的事实。
    【解决方案2】:

    您可能会发现此MSDN doc 很有帮助。

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

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

    【讨论】:

      【解决方案3】:

      据我所知,这是正确的。顺便说一句,这是一个带有everything you ever wanted to know about Strings的页面:

      【讨论】:

        【解决方案4】:

        每@JaredPar elsewhere on this site:

        您创建的底层字符串将 还需要一个连续的内存块 因为它表示为一个数组 字符数(数组需要连续 记忆)。

        我相信你不应该依赖它,因为它不是接口的一部分,但是如果这个语句是正确的,实现就是一个数组。鉴于我们对 char-strings 的了解以及 Microsoft 需要支持托管语言和本地语言之间的高效互操作,这对我来说是有意义的。

        MSDN只说这个,不保证存储是数组。

        字符串是一个顺序的集合 Unicode 字符用于 表示文本。 String 对象是一个 System.Char 的顺序集合 表示字符串的对象。这 String 对象的值是 顺序集合的内容, 并且该值是不可变的(即 它是只读的)。

        【讨论】:

          【解决方案5】:

          C# 只是一种语言。 string 关键字是 .Net 框架的 BCL 中 System.String 的别名。假设内部 String 是一个字符数组是非常安全的。来自 MSDN:

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

          【讨论】:

            【解决方案6】:

            这取决于你所说的“数组”是什么意思。

            如果您指的是随机访问、固定长度、可整数索引的对象集合的一般计算概念,那么是的,可以将字符串视为完全一样。 (一般的计算概念通常包括在内存中连续,但除非在少数情况下,例如在不安全的代码中使用指针,否则这在 C# 方面意义不大。

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

            在实践中,System.String 确实是作为 chars 的数组实现的,但不一定是这样。

            语言吹毛求疵,实用一点:

            如果您想对字符串执行与char[] 相同的操作,那么这通常会起作用(特别是,字符串是只读的)并且通常是最有效的方法,因为只要在概念上很简单。特别是,使用foreach 和使用在0str.Length - 1 之间移动的索引效果很好。类似地,可以对char[] 进行的很多操作都可以在string 上进行,例如CopyTo() 和强制转换为IEnumerable<char>

            如果你想真正拥有一个字符数组,那么你需要调用ToCharArray()

            【讨论】:

              猜你喜欢
              • 2016-05-04
              • 1970-01-01
              • 2015-08-09
              • 2020-10-05
              • 2012-08-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多