文字列は、.NET ではコピー オン ライト (より正確には、文字列プールに基づく) および参照型として実装されます。あなたがしようとしているのは、文字列を構成する基になる char[] を取得し、それを変更することです。ただし、string
コピーオンライトとして実装されているため、それが成功した場合、1 つの文字列だけでなくすべての文字列を変更することになります。
たとえば、コードが文字列を変更すると、次のようになります (誤った仮定を説明するため):
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'?
試してみると、基になるコンテンツがそのまま残るため、t は 'foo' になります。ToCharArray は基になるコンテンツのコピーを作成し、基になるコンテンツを保護して、同じ文字列オブジェクトへの他の参照が影響を受けないようにします。
これは、このようなコードが悪い習慣である理由でもあります:
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";
}
これが、文字列が不変として実装されている理由です。文字列への参照が異なるコンテンツを取得しないように保護するためです。
文字列プールの動作については、こちらも参照してください。