文字列を変更したはずが変わらない理由
string型は不変(イミュータブル)です。ToUpperやReplace、Trimなどのメソッドは新しい文字列を返すだけで、元の変数は書き換えません。
なぜエラーが出ないのか
出力: hello
(エラーなし)- C#は何も報告しません。文法として正しいためです
出力: hello- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 class Program { 2 static void Main(string[] args) { 3 string s = "hello"; 4 s.ToUpper() ; ^ 5 System.Console.WriteLine(s); 6 } 7 }
出力: hello
文字列は不変(immutable)です。ToUpper()は新しい文字列を返すだけで、元のsは変わりません。結果を使うには再代入が必要です。
直し方: s.ToUpper() を s = s.ToUpper() にします。
広告
広告スロット(未設定)
パターン2
1 class Program { 2 static void Main(string[] args) { 3 string s = "a-b-c"; 4 s.Replace("-", " ") ; ^ 5 System.Console.WriteLine(s); 6 } 7 }
出力: a-b-c
Replaceも新しい文字列を返す関数です。呼び出しただけでは元の変数は書き換わりません。
直し方: s.Replace("-", " ") を s = s.Replace("-", " ") にします。
パターン3
1 class Program { 2 static void Main(string[] args) { 3 string s = " hi "; 4 s.Trim() ; ^ 5 System.Console.WriteLine("[" + s + "]"); 6 } 7 }
出力: [ hi ]
Trim()も例外ではありません。前後の空白を取り除いた新しい文字列を返すだけです。
直し方: s.Trim() を s = s.Trim() にします。
よくある誤解
配列やListのメソッドは自分自身を変更するものが多いため、文字列のメソッドも同様だと誤解しがちです。結果を使うには戻り値を変数に代入し直す必要があります。
まとめ
文字列を変更したはずが変わらない理由は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。