В x86 есть машинные инструкции для работы с последовательностями, в частности со строками. Чтобы компилятор их использовал на самодельной строке он должен быть слишком умным. Гораздо легче зашить строки в язык, чтобы компилятор о них знал изначально. Это одна из причин почему операции со строками зашивают в язык.
Заманчивая идея реализации строк на буфере фиксированного размера (256?) разрушается при столкновении с реальностью. Если буфер взять слишком маленьким, то некоторые строки в него не уберутся, а если большим, то будет слишком большой перерасход памяти когда придётся иметь десятки миллионов строк одновременно.
То есть, в общем случае, строки должны быть доступны по указателю (или по индексу в массиве). Но длину таких строк нельзя менять. Какой смысл разрешать модификацию букв таких строк если длину нельзя менять? Даже если разрешить менять буквы не меняя длины, то в многопоточной программе это будет тормознее чем создать новую строку ибо лочить придётся при изменении каждой буквы. Опять же вопрос лочить что? Одно дело лочить только лишь одну эту строку, другое дело лочить весь строковый менеджер памяти, который используется для её аллокации. Наивно думать, что быстрее лочить одну лишь строку, так как внутри менеджера памяти при удалении строки придётся лочить и его самого и строку (два лока вместо одного). Так что нафиг-нафиг эта мутабельность.
Когда я писал свою UnmanagedString то специально сделал её неизменяемой по этим соображениям (жёсткая экономия памяти, свой аллокатор памяти, быстрая потокобезопасность).