Dan*_*Tao 37 .net c# string substring immutability
众所周知,.NET中的字符串是不可变的.(好吧,不是100%完全不可变,但设计不可变,无论如何都被任何理性的人使用.)
这使得基本上可以,例如,以下代码只在两个变量中存储对同一字符串的引用:
string x = "shark";
string y = x.Substring(0);
// Proof:
fixed (char* c = y)
{
c[4] = 'p';
}
Console.WriteLine(x);
Console.WriteLine(y);
Run Code Online (Sandbox Code Playgroud)
以上输出:
sharp
sharp
Run Code Online (Sandbox Code Playgroud)
显然,x并y指向同一个string对象.所以这是我的问题:为什么不Substring 总是与源字符串共享状态?字符串本质上是char*一个长度的指针,对吗?所以在我看来,至少在理论上应该允许分配单个内存块来保存5个字符,其中两个变量只指向该(不可变)块内的不同位置:
string x = "shark";
string y = x.Substring(1);
// Does c[0] point to the same location as x[1]?
fixed (char* c = y)
{
c[0] = 'p';
}
// Apparently not...
Console.WriteLine(x);
Console.WriteLine(y);
Run Code Online (Sandbox Code Playgroud)
以上输出:
shark
park
Run Code Online (Sandbox Code Playgroud)
Guf*_*ffa 25
有两个原因:
字符串元数据(例如长度)与字符存储在同一个内存块中,以允许一个字符串使用另一个字符串的部分字符数据,这意味着您必须为大多数字符串而不是一个字符串分配两个内存块.由于大多数字符串不是其他字符串的子字符串,因此额外的内存分配将比通过重用部分字符串获得的内存消耗更多.
在字符串的最后一个字符之后存储了一个额外的NUL字符,以使该字符串也可以被期望空终止字符串的系统函数使用.您不能在另一个字符串的子字符串后面添加额外的NUL字符.
Joe*_*Joe 12
我相信C#字符串是空终止的 - 虽然这是一个不应该与托管消费者有关的实现细节,但在某些情况下(例如编组)它很重要.
此外,如果子字符串共享具有更长字符串的缓冲区,则这意味着对短子字符串的引用将阻止收集更长的字符串.并且大鼠嵌套字符串引用的可能性指的是相同的缓冲区.
| 归档时间: |
|
| 查看次数: |
2032 次 |
| 最近记录: |