Будет ли Substring создавать еще один экземпляр C #? - PullRequest
2 голосов
/ 30 апреля 2019

Я новичок в C # строке Я запутался в

 Object.referenceEquals 

Я читал какую-то статью, в которой говорится, ReferenceEquals проверить, является ли это тот же самый экземпляр или нет в программе, которую я проверяю, если object.ReferenceEquals(s1, s4), даже если они указывают на те же данные, почему это ложно?

string s1 = "akhil";
string s2 = "akhil";

Console.WriteLine(object.ReferenceEquals(s1, s2)); //true
s2 = "akhil jain";
Console.WriteLine(object.ReferenceEquals(s1, s2)); //false
//Console.WriteLine(s1 == s2);
//Console.WriteLine(s1.Equals(s2));

string s3 = "akhil";
//1".Substring(0, 5);
Console.WriteLine(s3+" " +s1);
Console.WriteLine(object.ReferenceEquals(s1,s3)); //true


string s4 = "akhil1".Substring(0, 5);
Console.WriteLine(object.ReferenceEquals(s1, s4)); //confusion false why as s4 data is same as s1

Ответы [ 3 ]

2 голосов
/ 30 апреля 2019

Ссылки совпадают, потому что строковый литерал получает интернированный , Substring возвращает новую строку и новую ссылку, он не пытается повторно угадать ваши параметры и проверить пул интерна

String.Intern (String) Method

Общеязыковая среда выполнения сохраняет хранилище строк, поддерживая таблица, называемая внутренним пулом, которая содержит одну ссылку на каждая уникальная литеральная строка, объявленная или созданная программно в ваша программа. Следовательно, экземпляр литеральной строки с конкретное значение существует только один раз в системе.

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

Хотя, бесполезный факт 3454345.2 , поскольку .Net 2 , вы можете отключить его по разным причинам, у вас может быть

Составление Relaxations Enum

NoStringInterning Помечает сборку как не требующую интернирования строк-букв. В домене приложения, общий среда исполнения языка создает один строковый объект для каждой уникальной строки буквальный, а не делать несколько копий. Такое поведение называется внутренняя строка, требует создания вспомогательных таблиц, которые потреблять ресурсы памяти.

0 голосов
/ 30 апреля 2019

Значение object.ReferenceEquals равно false, поскольку оно проверяет, указывают ли обе ссылки на один и тот же объект.ReferenceEquals не проверяет равенство данных, но если оба объекта занимают один и тот же адрес памяти.

Как уже упоминалось в TheGeneral, строковые литералы интернируются и хранятся в таблице, называемой внутренним пулом.Это необходимо для эффективного хранения строковых объектов.

Когда строковый литерал назначен нескольким переменным, они указывают на один и тот же адрес в пуле интернов.Следовательно, вы получаете истину для object.ReferenceEquals.Но когда вы сравниваете это с подстрокой, в памяти создается новый объект.Это приводит к ложному результату при сравнении ссылок, поскольку это два разных объекта, занимающих разные области памяти.

Все динамически созданные строки или чтение из внешнего источника автоматически не интернируются.

ЕслиЕсли вы попробуете следующее, вы получите true для object.ReferenceEquals:

Console.WriteLine(object.ReferenceEquals(s1, string.Intern(s4)));

Вы можете проверить с помощью типов данных Primitive, что ReferenceEquals возвращает false, даже если одна переменная назначена другой.

int a = 10;
int b = a;
Console.WriteLine(ReferenceEquals(a, b)); //false

Это потому, что каждый тип примитива хранится отдельно.

0 голосов
/ 30 апреля 2019

При создании двух объектов ссылка не совпадает. Поэтому метод Object.ReferenceEquals возвращает false. Однако строки - это особый случай. Если вы объявляете строку в коде, CLR сохраняет ее в таблице. Это называется intern pool . Это приводит к тому, что две строки, которые были созданы с одним и тем же значением, ссылаются на один и тот же объект в памяти. Это заставит Object.ReferenceEquals вернуть true.

Когда строка образована какой-либо операцией в вашем коде, она автоматически не передается в пул. И поэтому он имеет другую ссылку, хотя содержимое строки может быть одинаковым. Это также объясняется в примечаниях к документации Object.ReferenceEquals здесь .

Обратите внимание, что метод String.Equals() вернет true. В C # вы также можете использовать оператор '==' для строк. Смотрите ваш скорректированный код ниже.

string s1 = "akhil";
string s2 = "akhil";

Console.WriteLine(s1.Equals(s2)); //true
s2 = "akhil jain";
Console.WriteLine(s1.Equals(s2)); //false

string s3 = "akhil";
Console.WriteLine(s3 + " " + s1);
Console.WriteLine(s1.Equals(s3)); //true

string s4 = "akhil1".Substring(0, 5);
Console.WriteLine(s1.Equals(s4)); //this now returns true as well
Console.WriteLine(s1 == s4);      //so does this
...