строка не изменяется по ссылке - PullRequest
0 голосов
/ 01 февраля 2012

Я создаю 2 переменные с именами a и b , затем инициализирую переменную a со значением «старт» и позже я назначаю переменную a переменной b и, наконец, я изменяю значение переменной a на end но переменную b не изменяется, а a и b являются справочными типами!

string a = "start"; // Declare and initialize a variable
string b = a; // Copy the variable's value to a new variable
a = "end"; // Modify the value of the original variable
//variable b don't change!!

Почему это не работает, как ожидалось?

Ответы [ 3 ]

18 голосов
/ 01 февраля 2012

Вы неправильно понимаете, что означает "ссылочный тип".

Думайте об этом так. Представьте себе два дома, один на Сезам-стрит 123 и один на Пеннислвании-авеню, 1600. Это объекты ссылочного типа .

Теперь представьте, что у вас есть два куска бумаги. Один говорит "Улица Сезам 123". Один говорит "1600 Пенсильвания авеню". Это не дома; Вы не можете перейти к этим листам бумаги. Это ссылки на дома.

Теперь представьте, что у вас есть два выдвижных ящика с надписью "a" и "b". Это переменные ссылочного типа .

Вы кладете бумагу «Улица Сезам 123» в кассету «а». Вы не кладете дом в ящик. Вы кладете ссылку на дом в ящик. Переменная ссылочного типа хранит ссылку на объект . Вот почему она называется переменной ссылочного типа .

Затем вы делаете ксерокопию бумаги в кассете «а» и кладете ее в кассету «б». «b» теперь содержит копию ссылки . Ящики "а" и "б" теперь относятся к одному и тому же дому . Если вы раскрасите этот дом в красный цвет, дом, на который ссылаются бумаги в обоих ящиках, будет красным, потому что есть только один дом, на который ссылаются обе бумаги. Есть две ссылки на один и тот же дом и две переменные, которые содержат одну ссылку на каждую.

Затем вы достаете бумагу из ящика "а" и уничтожаете ее. Вы заменяете его бумагой с надписью «1600 Пенсильвания Авеню».

Это ничего не изменило в ящике "b"! Когда вы сказали «b = a», это означает «сделайте фотокопию ссылки, которая находится в ящике a, и поместите ее в ящик b». не означает, что «ящики a и b теперь являются двумя разными именами для одного и того же ящика».

Это имеет смысл?

6 голосов
/ 01 февраля 2012

Это не то, как строки работают в C #, они не указатели. Более того, строки являются неизменяемыми, поэтому вы все равно не можете изменить их значение, просто назначьте новое. Поэтому, что бы вы ни пытались сделать, вам нужно это учитывать.

Тот факт, что оператор сравнения завершается успешно, заключается в том, что вы выполняете буквальное сравнение между символами, содержащимися в каждой строке, а не потому, что они "равны" в смысле памяти.

1 голос
/ 01 февраля 2012

Если вам нужно, чтобы строки были изменены по ссылке (функцией), вы можете поставить ref слева от типа аргумента.В противном случае вы могли бы создать класс MutableString, но лично мне не понадобилась бы изменяемая строка.

Вы также можете попробовать StringBuilder, но это не совсем строка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...