文字列が不変であるだけでなく、stringは参照型ですが、参照自体はそうではありません。つまり、string参照渡しですが、参照自体は値渡しです。
したがって、参照型の場合、(変更可能である限り) パラメーターによって参照されるオブジェクトを変更できますが、参照渡ししない限り、引数が参照するものを変更することはできません。
したがって、string変数が参照するものを変更しようとすると、次のようになります。
str = tmpStr;
ローカルで参照するものを変更しますstrが、元の引数が参照するものには影響しませんlocalString。
localStringこのように考えてください。引数が位置 1000 のオブジェクトを参照しているとしましょう。
localString
+---------------+ 1000
| 1000 | -----------------> +---------------+
+---------------+ | Count: 1 |
| Value: "" |
+---------------+
次に、メソッドに渡すlocalStringと、参照のコピーが作成され (as としてstr)、参照カウントが更新されます...
localString
+---------------+ 1000
| 1000 | -----------------> +---------------+
+---------------+ | Count: 2 |
| Value: "" |
str +---------------+
+---------------+ ^
| 1000 | ---------------------+
+---------------+
次に、str を新しい文字列に割り当てると、参照は変更されますstrが、変更されませんlocalString。
localString
+---------------+ 1000
| 1000 | -----------------> +---------------+
+---------------+ | Count: 1 |
| Value: "" |
str +---------------+
+---------------+ 2500
| 2500 | ---------------------> +---------------+
+---------------+ | Count: 1 |
| Value: ... |
+---------------+
したがって、元の参照ではなく、参照するstrもののみを変更した場合、それを変更したい場合は、参照渡しします。つまり、元の引数への参照になります (ptr から ptr に似ています)。strlocalStringstr
localString
+---------------+ 1000
| 2500 | ------------------> +---------------+
+---------------+ | Count: 2 |
^ | Value: "" |
str | +---------------+
+---------------+
| |
+---------------+
ここで、str変更すると参照も変更localStringされます。
localString
+---------------+ 1000
| 1000 | -----+ +---------------+
+---------------+ | | Count: 0 |
^ | | Value: "" |
str | | +---------------+
+---------------+ | 2500
| | +----------------> +---------------+
+---------------+ | Count: 1 |
| Value: ... |
+---------------+
そしてもちろん、元の文字列 (この例のように他に何も参照されていないと仮定) は、ガベージ コレクトすることができます...
そのため、本当にstringパラメーターを変更したい場合は、refまたはで渡すか、変更されoutた新しいバージョンを返すか、インスタンス メンバーに格納します (ただし、pass-by-instance-member はカップリングの高次であり、他のエラーを引き起こす可能性があります)。問題...)。