Я полагаю, что это "зависит", в основном от того, передает ли вызывающая сторона строку той же сборки, которая была интернирована с вашей строкой.
И вот почему:
ReferenceEquals делает то, что вы думаете, сравнивая области памяти, а не значение объекта ( MSDN ):
Вызвав метод ReferenceEquals, вы можете увидеть, что два
Строки фактически ссылаются на один и тот же объект в памяти.
Есть функция C #, называемая интернирование строк , которая, согласно Эрику Липперту:
Если у вас есть два одинаковых строковых литерала в одном модуле компиляции, то сгенерированный нами код гарантирует, что CLR создает только один строковый объект для всех экземпляров этого литерала в сборке. Эта оптимизация называется «интернирование строк».
Однако из того же поста интернирование по умолчанию не гарантируется для каждой строки:
Если вы писали компилятор на C # или у вас было какое-то другое приложение, в котором вы считали, что стоит того, чтобы тысячи одинаковых строк не занимали много памяти, вы можете заставить среду выполнения интернировать вашу строку с методом String.Intern.
И наоборот, если вы ненавидите интернирование с безрассудной страстью, вы можете заставить среду выполнения отключить интернирование всех строк в сборке с атрибутом CompilationRelaxation.
Чего бы вы ни пытались достичь, эта текущая реализация в лучшем случае выглядит ненадежной - я бы подумал переосмыслить то, что вы делаете.