2016-08-05 1 views
-6

Я знаю, что строки неотменяемы, после создания мы не можем его изменить, я прочитал, что если мы создадим новый строковый объект и присвоим ему значение, а затем мы назначим другое значение одному и тому же строковому объекту внутри, объект, созданный и назначенный новым значением. Скажем, у меня есть:Как работает строка в C#?

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

Если я пишу Console.WriteLine(str); возвращает cat. Итак, внутри есть два объекта? Но у них одно и то же имя? Как это работает? Я сделал некоторые исследования в Google, но я не нашел для меня достаточно убедительного мнения, поэтому я могу прояснить свои мысли об этом. Я знаю, что строки являются ссылочными типами, поэтому у нас есть объект в стеке со ссылкой на значение в куче, что происходит в этом случае? (См. Код выше).

Я загрузил фотографию, извинись, если я ошибаюсь в идее стека и кучи, поэтому я задаю этот вопрос. Отображает ли изображение то, что происходит в первой строке кода (string str = "dog";)? А потом что должно произойти во второй строке кода? Значение dog в куче меняется? А затем создается новый объект в стеке, ссылающийся на него? Тогда что происходит с объектом, который был там раньше? У них одно и то же имя? Прошу прощения за столько вопросов, но я думаю, что очень важно правильно понять это и узнать, что происходит за кулисами ... enter image description here

ответ

2

обзор String Interning или .Net String Intern table или CLR Intern Pool.
В общем случае среда выполнения Common Language Runtime (CLR) поддерживает таблицу [уникальных] строковых значений, и всякий раз, когда вы манипулируете строкой в ​​коде, CLR проверяет эту старую таблицу, чтобы узнать, уже ли новое значение, которое вы пытаетесь создать, там или нет. Если это так, он просто переназначает переменную, которую вы изменяете, чтобы указать на эту запись в пуле. Если нет, он добавляет значение в пул и возвращает эту новую ссылку. Старые значения в пуле, больше не ссылающиеся на переменные, получают сбор мусора.

+0

Мне очень сложно выбрать ответ, потому что все ваши ответы были очень описательными, теперь я выяснил об этом, спасибо !!! – AlexGH

1

Да, есть два объекта. Нет, у них нет одинакового имени. Попытайтесь не думать о переменной как о «имени» для самого объекта per se - это больше похоже на временное имя для местоположения объекта в памяти. (Причина, по которой несколько неверно думать о переменной как о «имени» для объекта, состоит в том, что у вас может быть несколько переменных, относящихся к одному и тому же объекту, но это не тот случай, когда объект имеет несколько «имен» как таковых, или что там это несколько объектов - вот как вы собираетесь хранить ссылку).

«строка str» изначально имеет ссылку на строку «собака». После того, как вы назначили «cat» на «str», переменная теперь имеет ссылку на строку «cat».

Обе строки все еще существуют в памяти (по крайней мере временно), но строка «собака» больше недоступна, потому что у вас нет ссылки на нее (и, следовательно, больше не «знают» ее местоположение). Вы не знаете заранее, как долго они будут существовать в памяти, хотя, поскольку сборщик мусора может удалить строку «собака» из памяти в любой момент, так как больше нет ссылок на нее.

Вы правильно относитесь к значению в стеке со ссылкой на объект в куче, кстати - это хорошее различие.

2

Вы близко. Ваша фотография точно отражает то, что происходит в первой строке кода. Тем не менее, все немного отличается от того, что вы описываете для второй строки кода.

Для строки str = "cat"; в куче создается второй строковый объект, а переменная str изменяется для обращения к этому новому объекту. Вы останетесь с str, указывая на "cat" и сирота "dog" объект на куче без ссылок на него.

Объект "dog" может быть очищен сборщиком мусора, поскольку ссылки на него отсутствуют.

4

Когда вы назначаете 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": 

Что происходит с «собакой»? Сейчас он недоступен, так как мы больше не имеем ссылки на его местоположение (в памяти, кучи, термины взаимозаменяемы в этой ситуации). Позже, когда сборщик мусора рассматривает память для очистки, он поймет, что ничего не говорится о «собаке», и он будет отмечать память для удаления и замены по мере необходимости.

Смежные вопросы