2013-09-29 3 views
5

Я недавно начал читать о изменяемых и неизменяемых объектах в C#, и постоянная вещь, которую я нахожу там, где я читаю, является непреложной шляпой, делает вещи небезопасными и полезными при использовании в качестве ключей в хеш-таблицы, но то, что я не понимаю, насколько это понятие идет, пока мы не можем изменить содержание, мы можем изменить ссылку, которая находится:Что это значит: «Неизменяемые строки - потокобезопасные»

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

Хотя здесь ссылка с изменяется на «Bye», но главным дело в том, что содержимое s (или, скорее, то, что оно указывало), изменилось, и с точки зрения программирования это одно и то же, так как это делает определенную функцию поточной или полезной в хэш-таблице, если строка изменена ??

+0

Взгляните на http://stackoverflow.com/questions/2365272/why-net-string-is-immutable –

+0

@Soner Gönül: прочитайте, что .... точно не проливает свет на вещь i ' m ask ... –

ответ

0

В вашем примере s переназначен для ссылки на другой объект string («Bye»), но объект, который ранее ссылался («Привет»), не изменился. Все, что имеет ссылку на строку «Привет» (другой поток, Dictionary и т. Д.), Не будет затронуто. Как вы упомянули, string неизменен - ​​его содержимое нельзя изменить после его создания. Например, если вы добавляете один из string в другой, вы получаете новый объект string. Два оригинальных объекта string остаются неизменными. Это то, что делает string поточно-безопасным и подходит для использования в хеш-таблице.

Ссылка sне потокобезопасный - для обеспечения безопасности потоков при использовании ссылки, вам нужно поставить блокировку вокруг опорной уступки, чтобы гарантировать, что один поток не пытался читать из когда другой поток писал.

+0

«Все, что имеет ссылку на строку« Привет »(другой поток, словарь и т. д.), не будет затронуто» - будет ли исходная строка не идти на GC в этом случае? и если это идет для GC, то нить или диктат сломаются .... я имею в виду, что происходит? к чему это относится? также мой второй комментарий к jdv-Jan de Vaan выше о словарях тоже применяется ... что произойдет в этом случае? –

2

Простой. Если вы должны были передать s код, который выполняется в другом потоке, этот код получит строку, на которую указывает s во время передачи этого параметра. Как и все строки в .net, со временем это не изменится, поэтому в вашем потоковом коде не нужно учитывать, что вы можете переназначить s на другое значение.

Если вы назначили «Bye» на s, исходная строка будет жить (пока не будет собран ее мусор), а ваша переменная s указывает на новую строку.

В словарях это несколько отличается. Если вы измените свой изменяемый ключ таким образом, чтобы его хэш-код менялся, словарь не смог найти ключ: хэш-код используется для поиска в индексе, и словарь не найдет правильную запись, если хэш-код будет меняться со временем. Таким образом, это действительно не требует неизменности, но неизменность обеспечит последовательное вычисление хэш-кодов.

Какая неизменность делает для вас, это дает возможность думать об объекте так, как если бы это был тип значения (например, int), о котором часто легче рассуждать.

+0

ok ...... но скажите мне, что предполагается, что строка была изменчивой ... если бы я передал ее как переменную в код, который работает в другом потоке .. он бы передал версию и будет работать с этим данных, даже если я изменил его позже ... правильно ?? –

+0

также в словаре, например.вы говорите, что если хэш изменится, ключ не будет найден, но не произойдет ли это с неизменяемой строкой? я изменил данные, на которые он ссылается, даже если строка в памяти для GC указывает на переменную, которая не содержит этих данных ... –

+0

Что касается вашего первого комментария: если строки были изменчивыми, можно было бы изменить string после того, как вы передали его в другой поток, и этот поток мог увидеть изменение. –