A string is in .NET implemented as copy-on-write (more exactly: based on a string pool) and as reference-type. What you're trying to do is get the underlying char[] that makes up the string and change that. However, since string is implemented as copy-on-write, if that were to succeed, you wouldn't just change one string but all of them.
For example, this is what would happen if your code would change the string: (to illustrate the incorrect assumption):
string s = "foo"; // create instance with foo
string t = s; // copy reference, contents aren't changed
char[] ch = s.ToCharArray(); // attempt to access underlying contents
ch[0] = 'b'; // attempts to change the underlying contents
Console.WriteLine(t); // 'boo'?
When you try it, t will be 'foo', because the underlying contents remain intact. ToCharArray makes a copy of the underlying contents, thereby protecting the underlying contents so that other references to the same string object are not affected.
This is also the reason code like this is a bad practice:
string s = "";
for (int i=0; i<10000; ++i)
{
// makes a new instance of the string, copies the contents
// and appends a single char... as you can see 10K times...
s = s + "a";
}
This is why strings are implemented as immutable: to protect references to a string from getting different content.
See also here about the behavior of the string pool.
sis unchanged.