Sven Groot hit the nail on the head. There is another consideration, an internal optimization that you can use in your code as well: interned strings. An interned string is one that has been added to a big hashtable internally in the CLR (they call it
a "pool"). This is used automatically for literal strings, so all literal strings with the same characters refer to the same memory location.
You can also explicitly intern a dynamically created string by calling Intern. To compare two interned strings for equality, you only have to compare addresses, and not the contained characters.
The concept of an interned string would be destroyed by mutable strings -- or at least, they could not be interned.