Мне было любопытно, как класс StringBuilder реализован внутри, поэтому я решил проверить исходный код Mono и сравнить его с Reflector дизассемблированным кодом реализации Microsoft. По сути, в реализации Microsoft используется char[]
, чтобы хранить внутреннее представление строки и кучу небезопасных методов для управления им. Это прямо и не вызывает никаких вопросов. Но я был смущен, когда обнаружил, что Mono использует строку внутри StringBuilder:
private int _length;
private string _str;
Первой мыслью было: "Какой бессмысленный StringBuilder". Но потом я понял, что можно изменить строку с помощью указателей:
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++;
}
Я немного программировал на C/С++, поэтому я не могу сказать, что этот код меня очень смутил, но я думал, что строки абсолютно неизменяемы (т.е. нет абсолютно никакого способа его мутировать). Итак, актуальные вопросы:
- Могу ли я создать полностью неизменяемый тип?
- Есть ли причина использовать такой код помимо проблем с производительностью? (небезопасный код для изменения неизменяемых типов)
- Являются ли строки неотъемлемо потокобезопасными или нет?