У меня есть два объекта в C #, и я не знаю, является ли он логическим или любого другого типа. Однако, когда я пытаюсь сравнить эти C # не дает правильный ответ. Я пробовал тот же код с VB.NET, и это было сделано!
Может кто-нибудь сказать мне, как это исправить, если есть решение?
C #:
object a = true;
object b = true;
object c = false;
if (a == b) c = true;
MessageBox.Show(c.ToString()); //Outputs False !!
VB.NET:
Dim a As Object = True
Dim b As Object = True
Dim c As Object = False
If (a = b) Then c = True
MessageBox.Show(c.ToString()) '// Outputs True
c#
.net
vb.net
comparison
Мохсен Саркар
источник
источник
a.Equals(b)
?a
вы получаете бокс и создаете коробку, содержащуюtrue
. При назначенииb
вы получаете еще один ящик, содержащийtrue
. Когда вы сравниваетеa
иb
, поскольку оба имеют тип времени компиляцииobject
, вы вызываете перегрузку,operator ==(object, object)
определенную Спецификацией языка C #. Эта перегрузка проверяет, идут ли ссылки на один и тот же объект. Поскольку у вас есть два поля, результат будетfalse
, и оператор «под» вашif
не будет работать. Чтобы лучше это понять, попробуйте изменить назначениеb
на это:object b = a;
теперь у вас есть только одна коробка.Ответы:
В C #
==
оператор (применительно к выражениям ссылочного типа) выполняет проверку равенства ссылок, если только он не перегружен . Вы сравниваете две ссылки, которые являются результатом преобразования в бокс, так что это разные ссылки.РЕДАКТИРОВАТЬ: С типами, которые перегружают
==
, вы можете получить различное поведение - но это основано на типе выражений во время компиляции . Например,string
предоставляет==(string, string
):Здесь первое сравнение использует перегруженный оператор, а второе использует сравнение ссылок «по умолчанию».
В VB
=
оператор выполняет гораздо больше работы - это даже не просто эквивалентно использованиюobject.Equals(x, y)
, поскольку такие вещиOption Compare
могут влиять на сравнение текста.По сути, операторы не работают одинаково и не должны работать одинаково.
источник
=
сделал в VB, но спецификация не очень ясна.bool == bool
сравнение.В дополнение к ответу Джона, который объясняет сторону C #, вот что делает VB:
В VB с
Option Strict On
помощью сравнения=
всегда проверяется равенство значений, а не равенство ссылок. Фактически, ваш код даже не компилируется после переключения,Option Strict On
потомуSystem.Object
что не определяетOperator=
. Вы должны всегда иметь эту опцию, она ловит ошибки более эффективно, чем мухоловка Венеры (хотя в вашем конкретном случае это слабое поведение на самом деле делает правильные вещи). 1На самом деле, с помощью
Option Strict On
VB ведет себя еще строже, чем в C #: в C #a == b
либо инициирует вызов,SomeType.operator==(a, b)
либо, если его нет, вызывает сравнение равенства ссылок (что эквивалентно вызовуobject.ReferenceEquals(a, b)
).В VB, с другой стороны, сравнение
a = b
всегда вызывает оператор равенства. 2 Если вы хотите использовать сравнение равенства ссылок, вы должны использоватьa Is b
(что, опять же, так же, какObject.ReferenceEquals(a, b)
).1) Вот хорошее указание на то, почему использование
Option Strict Off
является плохой идеей: я использовал VB.NET почти десять лет, с момента официального выпуска .NET до нескольких лет назад, и я абсолютно не знаю, чтоa = b
с этим делатьOption Strict Off
. Это делает какое-то сравнение на равенство, но что именно происходит и почему, понятия не имею. Однако это более сложно, чемdynamic
функция C # (потому что это опирается на хорошо документированный API). Вот что говорит MSDN:2) Джон упомянул одно исключение, строки, где сравнение на равенство делает еще кое-что из соображений обратной совместимости.
источник
Option Strict On
должно рассматриваться как уголовное преступление ...Экземпляры объекта не сравниваются с оператором "==". Вам следует использовать метод «равно». С оператором "==" сравниваются ссылки, а не объекты.
Попробуй это:
Полученные результаты:
Теперь попробуйте это:
Полученные результаты:
источник
operator ==
. Если вы переопределите этот оператор и не равно, то ваш вывод будет обратным. Ничто не присуще сравнению ссылокoperator ==
и ничего не присуще сравнению значений вEquals
. Это всего лишь два способа определения равенства; оба имеют стандартные реализации сравнения ссылок, и оба могут быть переопределены, чтобы делать то, что вы хотите, чтобы они делали. Единственное другое отличие состоит в том, чтоEquals
является виртуальным, аoperator ==
не является.==
- вы можете только перегрузить его.Проблема в том, что оператор == в C # - это вызов статического метода (ну, может быть, не технически, но может быть как таковой), основанного на типе времени компиляции двух параметров. Каковы фактические типы времени выполнения этих объектов, не имеет значения.
На основе этого типа времени компиляции компилятор определит, какую реализацию
operator ==
использовать. Он может использоватьobject
реализацию по умолчанию , может использовать одну из числовых перегрузок, предоставляемых языком, или это может быть реализация, определяемая пользователем.Это отличается от VB тем, что VB не определяет реализацию во время компиляции. Он ожидает выполнения и проверяет два заданных параметра, чтобы определить, какую реализацию
==
оператора он должен использовать.Ваш код содержит логические значения, но они находятся в переменных, которые имеют тип
object
. Поскольку переменная имеет типobject
, компилятор C # используетobject
реализацию==
, которая сравнивает ссылки , а не экземпляры объекта. Поскольку логические значения являются блоками, они не имеют одинаковых ссылок, даже если их значения одинаковы.Код VB не имеет значения, какой тип переменной. Он ждет до времени выполнения, а затем проверяет две переменные, видит, что они на самом деле имеют тип boolean, и поэтому использует реализацию логического
==
оператора. Эта реализация сравнивает значения логических значений, а не их ссылок (и логические значения будут распакованы перед вызовом этого оператора, поэтому сравнение ссылок даже не имеет смысла). Поскольку значения логических значений совпадают, возвращается значение true.источник
=
делает в VB, чтобы сказать наверняка.=
вместе со всеми другими операторами реляционного сравнения, такими как<
,>=
и т. Д. , получают специальную обработку, когда обе стороны или одна из сторон оператораObject
. Эта специальная обработка сделана так, чтобы программисты VB6, которые привыкли использовать тип, известный как доVariant
.NET VB, могли использоватьObject
в VB.Net способами, которые они использовалиVariant
прежде.Option Strict On
, VB=
смещен в сторону распаковкиObject
до тех пор, пока не сможет получить строку или число.