System.String的内部

Bow*_*opa 13 c# string reflection

我使用反射来查看System.String的内部字段,我找到了三个字段:

m_arrayLength

m_stringLength

m_firstChar
Run Code Online (Sandbox Code Playgroud)

我不明白这是如何工作的.

m_arrayLength是某个数组的长度.这个阵列在哪里?它显然不是字符串类的成员字段.

m_stringLength很有意义.这是字符串的长度.

m_firstChar是字符串中的第一个字符.

所以我的问题是字符串的其余字符在哪里?如果不在字符串类中,则存储字符串的内容在哪里?

Mar*_*ell 12

第一个char提供&m_firstChar对存储器中缓冲区中第一个字符的地址的访问(via ).长度告诉它有多少字符string,.Length效率高(比查找nul字符更好).请注意,字符串可以超大(特别是如果使用StringBuilder,以及一些其他方案创建),因此有时实际缓冲区实际上比字符串长.所以跟踪这个很重要.例如,StringBuilder实际上会在其缓冲区中变换一个字符串,因此在创建更大的缓冲区之前需要知道它可以添加多少(AppendInPlace例如,参见参考资料).

  • @paxdiablo我故意使用"缓冲区"这个词,而不是字符串或数组 - 因为它不是;-p`tring`是.NET中的两种类型之一(**with*with arrays),具有不确定的大小.缓冲区从字段m_firstChar的地址开始.你可以说字符串是*类似地*实现了一个数组,而不是*封装*一个数组(它没有;这里*没有`char []`). (2认同)

Eil*_*lon 10

许多实现System.String是在本机代码(C/C++)中而不是在托管代码(C#)中.如果您查看反编译代码,您会看到大多数"有趣"或"核心"方法都使用此属性进行修饰:

[MethodImpl(MethodImplOptions.InternalCall)]
Run Code Online (Sandbox Code Playgroud)

只有一些辅助/便利API在C#中实现.

那么字符串的字符存储在哪里?这是绝密!深入了解CLR的核心本机代码实现.