Вы поняли, что вы читали. Да, строки неизменны. Это означает, что вы не можете изменить существующую строку.Это не работы:
string x = "Hello";
x[3] = 'q';
Когда вы конкатенации строк, вы получите новый:
string a = "a";
string b = "b";
string c = a+b; // You get a new string and a and b are unchanged.
Даже если вы самостоятельно конкатенации, вы получаете новую строку:
string a = "a";
a += "b"; // The same as a = a + "b" and yields a new string.
Но присваивание переменной (или переходя к функции или возврата из функции, и т.д.) не создает новую строку.
Строки являются «ссылочными типами». Это означает, что эта переменная:
string a = "Hello";
Это просто ссылка на строку. Делать это:
string b = a;
Просто присваивает ссылку к переменной. Он не изменяет строку.
Или, если положить его в терминах C: ссылочные переменные указатели к объектам. Рассмотрим:
string a = "Hello"; // a now points to the string object
string b = a; // b now points to the same object.
Что неизменность означает, что вы не можете изменить память о том, что указатель указывает на (сама строка объекта). Но переменная указателя столь же изменчива, как и всегда. Вы можете присвоить ему другой адрес.
Чтобы вернуться к исходному примеру:
string first = "hello"; // Allocates memory for "hello" and points first to it.
string second = "Bye"; // Allocates memory for "Bye" and points second to it.
first = second; // Assigns the address of second to first.
В конце концов, как first
и second
указывают на тот же адрес, который является адресом строки Bye
. Память строки hello
теперь не найдена (нет указателей на нее, она недоступна). Сборщик мусора вернет его через некоторое время.
Добавлено: Еще одна аналогия с С. строковые переменные .NET несколько, как это:
const char* str;
Это указатель на константу. Вы можете изменить указатель, но вы не можете изменить материал, на который он указывает.
Добавлено 2: Вы должны прочитать о типах значений и типах ссылок в .NET. Вкратце, типы значений - все типы struct
, а ссылочные типы - все типы class
. Типы значений копируются при назначении (или когда они передаются/возвращаются из функции); ссылочные типы - указатели.
Обратите внимание, что здесь есть одна неинтуитивная деталь. Класс object
, который является базовым классом типов ALL, является ссылочным типом. Однако типы значений наследуются от него, и вы можете присвоить тип значения переменной типа object
. Если вы это сделаете, это вызовет что-то, называемое boxing, и оно включает в себя создание копии значения, поэтому это немного дорогая операция.
Другими словами, вы хотите узнать адрес памяти 'first' (до и после). Мне это никогда не нужно, но, возможно, посмотрите http://stackoverflow.com/questions/588817/c-sharp-memory-address-and-variable? –
«Каждый раз, когда вы назначаете новое значение существующему строковому объекту ...» - вы не назначаете существующий строковый объект. Вы назначаете * переменную *. Вам нужно различать переменные и объекты. –