Это определенно связано с интернированием строк. Хеш-коды никогда не рассчитываются при сравнении ссылок с object.ReferenceEquals
.
Из спецификации C #, раздел 2.4.4.5:
Каждый строковый литерал не
обязательно привести к новой строке
пример. Когда две или более строки
литералы, которые эквивалентны в соответствии
на оператор равенства строк
(§7.9.7) появляются в той же программе,
эти строковые литералы относятся к
тот же экземпляр строки.
Обратите внимание, что строковые константные выражения в этом случае считаются литералами, поэтому:
string x = "a" + "b";
string y = "ab";
Гарантируется, что x
и y
также относятся к одному и тому же объекту (т. Е. Они являются одинаковыми ссылками).
Когда спецификация, кстати, говорит «программа», это действительно означает «сборка». Поведение одинаковых строк в разных сборках зависит от таких вещей, как CompilationRelaxations.NoStringInterning
и точной ситуации реализации и времени CLR (например, является ли сборка ngen'd или нет).