Как определить смысл сравнения объектов 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 шт):

Автор решения: CrazyElf

True

Правила простые:

  • Строки сравниваются по значению
  • Объекты object сравниваются по адресу
  • В общем случае каждая переменная получает свой адрес, но компилятор может оптимизировать какие-то вещи, в частности давать одну и ту же ссылку на одинаковые литералы

В данном случае компилятор заранее "вычислил" из выражения "abc" + "cba" литерал "abccba", а всем одинаковым строкам-литералам компилятор для экономии даёт один адрес, чтобы зря не забивать память. Поскольку строки в C# неизменяемые, от этого только польза, проблем никаких не будет.

А вот строка s1 "вычисляется" (интерполируется) уже во время исполнения программы, адрес у неё поэтому другой. Компилятор не тратит время на поиск дубликатов строк во время исполнения. Хотя строки можно интернировать для экономии памяти (давать ссылку на уже имеющуюся такую же строку в памяти), но это нужно делать в явном виде, поскольку это расходует драгоценное время выполнения программы, которое .NET всячески пытается оптимизировать и поэтому старается не делать лишних телодвижений во время исполнения программы без особой нужды или без явных указаний программиста.

var s1 = string.Intern(string.Format("{0}{1}", "abc", "cba"));
...
Console.WriteLine((object)s1 == (object)s2);
// True
→ Ссылка