There are five common ways by which a class data store data that cannot be modified outside the storing class' control:
- As value-type primitives
- By holding a freely-shareable reference to class object whose properties of interest are all immutable
- By holding a reference to a mutable class object that will never be exposed to anything that might mutate any properties of interest
- As a struct, whether "mutable" or "immutable", all of whose fields are of types #1-#4 (not #5).
- By holding the only extant copy of a reference to an object whose properties can only be mutated via that reference.
Because strings are of variable length, they cannot be value-type primitives, nor can their character data be stored in a struct. Among the remaining choices, the only one which wouldn't require that strings' character data be stored in some kind of immutable object would be #5. While it would be possible to design a framework around option #5, that choice would require that any code which wanted a copy of a string that couldn't be changed outside its control would have to make a private copy for itself. While it hardly be impossible to do that, the amount of extra code required to do that, and the amount of extra run-time processing necessary to make defensive copies of everything, would far outweigh the slight benefits that could come from having string be mutable, especially given that there is a mutable string type (System.Text.StringBuilder) which accomplishes 99% of what could be accomplished with a mutable string.