5

私は最近、C#の可変オブジェクトと不変オブジェクトについて読み始めました。どこを読んでも、不変であることはスレッドセーフであり、ハッシュテーブルのキーとして使用すると便利ですが、概念が理解できないことは理解できませんコンテンツを変更することはできませんが、次の参照を変更できます。

string s = "Hi";
s = "Bye";

ここでは s の参照が "Bye" に変更されていますが、主なことは s の内容 (またはそれが指していたもの) が変更され、プログラミングの観点からは同じであるということです。文字列が変更された場合、特定の関数をスレッドセーフにするか、ハッシュテーブルで使用可能にしますか??

4

2 に答える 2

2

単純。別のスレッドで実行されるコードに渡す場合、このコードは、パラメーターが渡された時点で がs指す文字列を受け取ります。.net のすべての文字列と同様に、時間の経過とともに変化しないため、別の値にs再割り当てする可能性があることをスレッド化されたコードで考慮する必要はありません。s

"Bye" を に割り当てるとs、元の文字列は (そのガベージ コレクションまで) 存続し、変数sは新しい文字列を指します。

辞書では、少し異なります。ハッシュコードが変更されるような方法で可変キーを変更すると、ディクショナリはキーを見つけられなくなります。ハッシュコードはインデックスの検索に使用され、ハッシュコードが時間の経過とともに変化すると、ディクショナリは正しいレコードを見つけられなくなります。したがって、これは実際には不変性を必要としませんが、不変性によりハッシュコードの一貫した計算が保証されます。

不変性によって、オブジェクトが値型 (int など) であるかのように考えることができるようになります。

于 2013-09-29T16:53:48.110 に答える
0

あなたの例でsは、別のstringオブジェクト (「さようなら」) を参照するように再割り当てされますが、s以前に参照したオブジェクト (「こんにちは」) は変更されていません。文字列 "Hi" への参照を持つその他のもの (別のスレッド、 aDictionaryなど) は影響を受けません。あなたが言及したように、stringそれは不変です-一度作成すると内容を変更することはできません。たとえば、 1 つstringを別のオブジェクトに追加すると、新しいstringオブジェクトが得られます。2 つの元のstringオブジェクトは同じままです。これにより、stringスレッドセーフになり、ハッシュテーブルでの使用に適しています。

参照s はスレッド セーフではありません。参照を使用するときにスレッド セーフを確保するには、参照の代入をロックして、別のスレッドが書き込みを行っている間に別のスレッドが参照から読み取ろうとしないようにする必要があります。それ。

于 2013-09-29T16:46:56.393 に答える