C# == оператор в окне Immediate ведет себя по-другому, чем во времени выполнения

Попробуйте следующее в окне Immediate:

object a1 = "a";
object a2 = "a";
a1==a2 // outputs false

и Вы будете видеть это a1 == a2 выводы false.

Однако во времени выполнения или в приложении окна или в консоли, Вы доберетесь true:

object t1 = "a";
object t2 = "a";
MessageBox.Show((t1 == t2).ToString()); // outputs true

Поведение во время выполнения согласовывается с определением для == оператор и строки.

Кто-либо знает если это ошибка в окне Immediate?

9
задан Joachim Sauer 25 May 2010 в 13:36
поделиться

3 ответа

Это не ошибка; причина того, что ваш исполняемый код работает, заключается в том, что эти строки интернированы (то есть в памяти есть только одно представление этих конкретных последовательностей символов. Каждая ссылка на константу «a» относится к одной и той же точке в объем памяти). В непосредственном окне для каждой создается новая строка, поэтому, хотя их содержимое одинаково, объекты указывают на разные места в памяти.

Использование оператора == для ссылочного типа выполняет сравнение ссылок (кроме случаев, когда указывается конкретный тип в качестве объекта, а не то, что объект - то есть ] объект в данном случае, а не строка - изменяет это поведение). Поскольку скомпилированные буквальные строки интернированы, они имеют одну и ту же ссылку. Поскольку строки непосредственного окна являются новыми строками, они не имеют той же ссылки.

2
ответ дан 4 December 2019 в 11:04
поделиться

Возможно, во время выполнения компилятор оптимизирует строковые литералы, чтобы они указывали на одно и то же место ссылки, но в непосредственном окне эта оптимизация не происходит.

2
ответ дан 4 December 2019 в 11:04
поделиться

То, что вы описываете, является правильным поведением.

Определение == в Object сравнивает ссылки своих аргументов. Это отличается от реализации == для String, которая сравнивает значения строк. Операторы в C# не являются виртуальными. Это означает, что даже если ваши объекты на самом деле являются строками, поскольку статическим типом является object, будет вызван == из Object, то есть будет произведено сравнение по ссылке.

В C# строки могут быть интернированы в пуле интернов. Обычно при создании новых строк во время выполнения программы вы получаете ссылку на совершенно новый строковый объект. Чтобы получить интернированную строку, можно вызвать метод string.Intern. Однако когда вы компилируете код C#, литеральные строки интернируются автоматически, поэтому, если в вашем коде в двух местах встречается одна и та же литеральная строка, вы получите ссылку на один и тот же строковый объект.

В непосредственном окне строки, очевидно, не интернируются - каждый раз создаются новые строки, даже если они имеют одно и то же значение. Но в .NET нет требования, что все строки должны быть интернированы, поэтому я не считаю это ошибкой.

Ваш код не должен зависеть от того, являются ли строки интернированными или нет, поскольку это деталь реализации.

15
ответ дан 4 December 2019 в 11:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: