I was curious how the StringBuilder class is implemented internally, so I decided to check out Mono's source code and compare it with Reflector's disassembled code of the Microsoft's implementation. Essentially, Microsoft's implementation uses char[] to store a string representation internally, and a bunch of unsafe methods to manipulate it. This is straightforward and did not raise any questions. But I was confused, when I found that Mono uses a string inside StringBuilder:
private int _length;
private string _str;
The first thought was: "What a senseless StringBuilder". But then I figured out that it is possible to mutate a string using pointers:
public StringBuilder Append (string value)
{
// ...
String.CharCopy (_str, _length, value, 0, value.Length);
}
internal static unsafe void CharCopy (char *dest, char *src, int count)
{
// ...
((short*)dest) [0] = ((short*)src) [0]; dest++; src++;
}
I used to program in C/C++ a little, so I can't say that this code confused me much, but I thought that strings are completely immutable (i.e there is absolutely no way to mutate it). So the actual questions are:
- Can I create a completely immutable type?
- Is there any reason to use such code apart from performance concerns? (unsafe code to change immutable types)
- Are strings then inherently thread-safe or not?