Оператор C # == в немедленном окне ведет себя иначе, чем во время выполнения - PullRequest
9 голосов
/ 25 мая 2010

Попробуйте следующее в окне «Немедленно»:

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

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

Кто-нибудь знает, если это ошибка в Немедленном окне?

Ответы [ 4 ]

15 голосов
/ 25 мая 2010

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

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

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

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

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

2 голосов
/ 25 мая 2010

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

2 голосов
/ 25 мая 2010

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

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

0 голосов
/ 18 марта 2011

Я бы предположил, что если вы отключите оптимизацию, то НЕ-немедленная версия также вернет false. Как уже говорилось, это не ошибка, а странность из-за оптимизаций, которые происходят внутри компилятора, но не в непосредственном окне.

...