Ссылка на строку - PullRequest
       4

Ссылка на строку

0 голосов
/ 21 июня 2011

Если a и b являются ссылками на один и тот же объект, почему значение a не меняется, когда мы меняем значение b в part3 . И если я предполагаю, что (как в part3 ), что b разыменовывается, когда я передаю ему новую литеральную строку, почему он также не разыменовывается в part2 , когда я передаю "foo" Литеральная строка (ReferenceEquals возвращает true).

//part1
string a = "foo";
string b = a;
System.Console.WriteLine("\na = {0}\nb = {1}", a, b); //a=foo b=foo
System.Console.WriteLine("a == b : {0}", a == b);//True
System.Console.WriteLine("ReferenceEquals(a, b): {0}", ReferenceEquals(a, b));//True

//part2
b = "foo";
System.Console.WriteLine("\na = {0}\nb = {1}", a, b);//a=foo b=foo
System.Console.WriteLine("a == b : {0}", a == b);//True
System.Console.WriteLine("ReferenceEquals(a, b): {0}", ReferenceEquals(a, b));//True

//part3
b = "bar";
System.Console.WriteLine("\na = {0}\nb = {1}", a, b);//a=foo b=bar
System.Console.WriteLine("a == b : {0}", a == b);//False
System.Console.WriteLine("ReferenceEquals(a, b): {0}", ReferenceEquals(a, b));//False

Ответы [ 5 ]

7 голосов
/ 21 июня 2011

a и b оба ссылаются на один и тот же объект.
Однако вы меняете b, а не объект.

String объекты неизменны и не могут быть изменены.

Когда вы пишете b = "foo", вы меняете b, чтобы ссылаться на другой экземпляр String.


Однако строковые литералы интернированы , поэтому запись "foo" всегда даст один и тот же String экземпляр.

Вы можете получить два разных String экземпляра с одинаковым значением, вызвав String.Copy:

string a = "foo";
string b = "foo";
Console.WriteLine(ReferenceEquals(a, b));    //True

b = String.Copy("foo");
Console.WriteLine(ReferenceEquals(a, b));    //False
3 голосов
/ 21 июня 2011

Если вы что-то измените, например a = "newstring";, это означает, что 'a' указывает на новую ссылку .

Строки неизменны -> вы не может изменить саму строку (a[0] = 'b';).

В part2, когда вы назначаете некую ранее использованную константу, используется ссылка на старую.Это называется «Interning».

Если вы сделали b = "fo" + "o";, ссылки не будут равны (в этом примере они будут, потому что компилятор оптимизирует это, но если строка создается не так, как используется напрямую)ссылки совпадают).

var a = "foo";
var b = "fo";
b = b + "o";
// in this point, the references AREN'T equal.
b = string.Intern(b);
// in this point, the references ARE equal.
1 голос
/ 21 июня 2011

"Строки являются неизменяемыми - содержимое строкового объекта не может быть изменено после создания объекта, хотя синтаксис заставляет его выглядеть так, как будто вы можете это сделать."

См. http://msdn.microsoft.com/en-us/library/362314fe.aspx

0 голосов
/ 21 июня 2011

a и b оба ссылаются на один и тот же объект. Как можно изменить, если вы присваиваете 'a' для 'b', а затем меняете значение 'b'

0 голосов
/ 21 июня 2011

a и b являются ссылками на одну и ту же вещь в части 1

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

В части 3 вы меняете ссылку только на b. a остается ссылкой на "foo", как это было раньше.

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