Как определить смысл сравнения объектов C#
var s1 = string.Format("{0}{1}", "abc", "cba");
var s2 = "abc" + "cba";
Console.WriteLine(s2.GetHashCode());
var s3 = "abccba";
Console.WriteLine(s3.GetHashCode());
Console.WriteLine(s1 == s2);
Console.WriteLine((object)s1 == (object)s2);
Console.WriteLine(s2 == s3);
Console.WriteLine((object)s2 == (object)s3);
- что в итоге будет выведено на консоль в последней строке? Почему? ответ пока такой: тру, ложно, тру, и ???
Ответы (1 шт):
Правила простые:
- Строки сравниваются по значению
- Объекты
object
сравниваются по адресу - В общем случае каждая переменная получает свой адрес, но компилятор может оптимизировать какие-то вещи, в частности давать одну и ту же ссылку на одинаковые литералы
В данном случае компилятор заранее "вычислил" из выражения "abc" + "cba"
литерал "abccba"
, а всем одинаковым строкам-литералам компилятор для экономии даёт один адрес, чтобы зря не забивать память. Поскольку строки в C#
неизменяемые, от этого только польза, проблем никаких не будет.
А вот строка s1
"вычисляется" (интерполируется) уже во время исполнения программы, адрес у неё поэтому другой. Компилятор не тратит время на поиск дубликатов строк во время исполнения. Хотя строки можно интернировать для экономии памяти (давать ссылку на уже имеющуюся такую же строку в памяти), но это нужно делать в явном виде, поскольку это расходует драгоценное время выполнения программы, которое .NET
всячески пытается оптимизировать и поэтому старается не делать лишних телодвижений во время исполнения программы без особой нужды или без явных указаний программиста.
var s1 = string.Intern(string.Format("{0}{1}", "abc", "cba"));
...
Console.WriteLine((object)s1 == (object)s2);
// True