2016-08-05 6 views
-6

私は文字列が変更不可能であることを知っています。私たちは変更できません。新しい文字列オブジェクトを作成し、それに値を割り当ててから、同じ文字列オブジェクトに別の値を割り当てます。作成され、新しい値で割り当てられたオブジェクト。のは、私が持っているとしましょう:私はConsole.WriteLine(str);を書く文字列はどのようにC#で動作しますか?

string str = "dog";    
str = "cat"; 

場合、それはcatを返します。 内部には2つのオブジェクトがありますか?しかし、彼らは同じ名前を持っていますか?どのように機能するのですか?私はGoogleに関するいくつかの調査をしましたが、私はまだ私に十分なものを見つけていないので、私はこれについての私の考えを明確にすることができます。 私は文字列が参照型であることを知っているので、スタック内にヒープの値を参照するオブジェクトがあります。この場合、何が起きていますか?(上記のコードを参照)。

写真をアップロードしました。スタックのアイデアやヒープが間違っていると私はお詫びします。私はこの質問をしています。 写真は、コードの最初の行(string str = "dog";)に何が起こっているかを反映していますか?そして、コードの2行目で何が起こるはずですか?ヒープ内のdogの値は変更されますか?そして、それを参照するスタック内の新しいオブジェクトが作成されますか?それでは、以前にあったオブジェクトはどうなりますか?彼らは同じ名前ですか? 非常に多くのご質問をおかけして申し訳ありませんが、正しく理解して何が起こっているのかを知ることは非常に重要だと思います... enter image description here

答えて

2

レビューString Interningまたは.Net String Intern tableまたはCLR Intern Poolです。
CLR(Common Language Runtime)は[ユニークな]文字列値のテーブルを保持しています。コード内の文字列を操作すると、CLRはこのインターンテーブルを調べて、作成しようとしている新しい値が既にそこにいるかどうか。そうであれば、変更している変数をインテルプールのそのエントリを指すように再割り当てするだけです。そうでない場合は、プールに値を追加し、その新しい参照を返します。プール内の古い値は、もはや変数によって参照されなくなり、ガベージコレクトされます。

+0

あなたの回答のすべてが非常に説明的なので、私は答えを選ぶのが非常に難しいです、私はこの問題について、今感謝しています! – AlexGH

1

はい、2つのオブジェクトがあります。いいえ、彼らは同じ名前を持っていません。変数をオブジェクト自体の "名前"と考えることは避けてください。それ自体はです。これは、メモリ内のオブジェクトの場所の一時的な名前によく似ています。 (変数をオブジェクトの「名前」と考えるのがやや誤解を招く理由は、同じオブジェクトを参照する複数の変数を持つことができるということです。オブジェクトにはいくつかの「名前」自体が存在するわけではありません。いくつかのオブジェクトがあります。つまり、参照を格納する方法です。

"string str"は、最初に "dog"という文字列への参照を持っています。 "cat"を "str"に割り当てた後、変数には "cat"という文字列への参照が追加されました。

どちらの文字列もまだメモリに存在しますが(少なくとも一時的に)、「dog」文字列は参照できないためアクセスできなくなりました。ガベージコレクタはメモリへの参照がなくなったので、ガベージコレクタがメモリから "dog"文字列を削除する可能性があるため、メモリ内にどれだけ長く存在するかは事前にわかりません。

ところで、ヒープ上のオブジェクトへの参照を使ってスタック上の値が正しいと思います。それは良い違いです。

2

もうすぐです。あなたの写真は、コードの最初の行で何が起こるかを正確に表しています。ただし、コードの2行目で説明する内容とは少し異なります。

str = "cat";の行では、2番目の文字列オブジェクトがヒープに作成され、str変数がその新しいオブジェクトを参照するように変更されます。 str"cat"を指しており、ヒープ上の孤児"dog"のオブジェクトは参照されていません。

オブジェクトが参照されていないため、"dog"オブジェクトがガベージコレクタによってクリーンアップされる可能性があります。

4

「dog」にstrを割り当てると、上で説明したようにメモリに格納されます。参照変数strは、インスタンス化した文字列の場所を「指し示しています」。

str => MEMORY LOCATION "1": "dog" 
     MEMORY LOCATION "2": 
     MEMORY LOCATION "3": 

strがあなたの新しい文字列、「猫」に再割り当てされた場合、それはあまりにもメモリ内に作成され、現在strされ、それは新しい場所に「猫」で指すように調整されています。

 MEMORY LOCATION "1": "dog" 
str => MEMORY LOCATION "2": "cat" 
     MEMORY LOCATION "3": 

「犬」はどうなりますか?現在のところ、その場所への参照がなくなるため(メモリ、ヒープ、用語はこの状況では互換性があります)、事実上アクセス不可能になります。後で、ガベージコレクタがメモリをクリーニングするかどうかを確認すると、 "dog"を参照するものは何もないことがわかり、必要に応じてメモリを削除して置き換えるようにマークします。

関連する問題