Eu tenho dois objetos em c # e não sei se é booleano ou qualquer outro tipo. No entanto, quando eu tento comparar esses c # falha em dar a resposta certa. Eu tentei o mesmo código com o VB.NET e foi isso!
Alguém pode me dizer como corrigir isso, se houver uma solução?
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
Mohsen Sarkar
fonte
fonte
a.Equals(b)
?a
você, obtenha o boxe e crie uma caixa contendotrue
. Quando você atribui ab
você, obtém outra caixa contendo tambémtrue
. Ao comparara
eb
, como os dois são do tipo tempo de compilaçãoobject
, você chama a sobrecargaoperator ==(object, object)
definida pela Especificação de idioma do C #. Essa sobrecarga verifica se as referências vão para o mesmo objeto. Como você tem duas caixas, o resultado éfalse
e a instrução "under"if
não será executada. Para entender isso melhor, tente alterar a atribuiçãob
para:object b = a;
Agora você tem apenas uma caixa.Respostas:
Em C #, o
==
operador (quando aplicado a expressões de tipo de referência) executa uma verificação de igualdade de referência, a menos que esteja sobrecarregada . Você está comparando duas referências que resultam de conversões de boxe, portanto, essas são referências distintas.EDIT: Com tipos que sobrecarregam
==
, você pode obter um comportamento diferente - mas isso é baseado no tipo de expressões em tempo de compilação . Por exemplo,string
fornece==(string, string
):Aqui, a primeira comparação está usando o operador sobrecarregado, mas a segunda está usando a comparação de referência "padrão".
No VB, o
=
operador faz muito mais trabalho - nem sequer é equivalente ao usoobject.Equals(x, y)
, pois coisas como issoOption Compare
podem afetar a comparação do texto.Fundamentalmente, os operadores não funcionam da mesma maneira e não pretendem funcionar da mesma maneira.
fonte
=
fez no VB, mas a especificação não é muito clara.bool == bool
comparação.Além da resposta de Jon, que explica o lado C #, aqui está o que o VB faz:
No VB com
Option Strict On
, uma comparação via=
sempre testa a igualdade de valor e nunca a igualdade de referência. De fato, seu código nem compila uma vez que você alternaOption Strict On
porqueSystem.Object
não define umOperator=
. Você deve sempre ter essa opção ativada, pois captura bugs com mais eficiência do que uma armadilha de venus (embora no seu caso particular esse comportamento negligente realmente faça a coisa certa). 1Na verdade, com
Option Strict On
, VB comporta-se ainda mais rigoroso do que o C #: Em C #,a == b
quer gatilhos uma chamada paraSomeType.operator==(a, b)
ou, se este não existir, comparação de igualdade de referência invoca (que é equivalente a chamarobject.ReferenceEquals(a, b)
).No VB, por outro lado, a comparação
a = b
sempre chama o operador de igualdade. 2 Se você quiser usar a comparação de igualdade de referência, precisará usara Is b
(que é, mais uma vez, o mesmo queObject.ReferenceEquals(a, b)
).1) Aqui está uma boa indicação do porquê usar
Option Strict Off
uma péssima idéia: usei o VB.NET por quase uma década, desde o lançamento oficial do .NET até alguns anos atrás, e não faço ideia do quea = b
fazOption Strict Off
. Faz algum tipo de comparação de igualdade, mas o que exatamente acontece e por que, não faz ideia.dynamic
Porém, é mais complexo que o recurso do C # (porque isso depende de uma API bem documentada). Aqui está o que o MSDN diz:2) Jon mencionou uma exceção, strings, em que a comparação de igualdade faz mais algumas coisas por razões de compatibilidade com versões anteriores.
fonte
Option Strict On
tem de ser considerada uma ofensa criminal ...Instâncias de objeto não são comparadas com o operador "==". Você deve usar o método "igual". Com o operador "==" estão comparando referências, não objetos.
Tente o seguinte:
Resultados:
Agora, tente o seguinte:
Resultados:
fonte
operator ==
. Se você substituir esse operador e não for igual, sua saída será revertida. Não há nada inerente à comparação de referênciasoperator ==
e nada inerente à comparação de valores emEquals
. São apenas duas maneiras de determinar a igualdade; ambos têm implementações padrão de uma comparação de referência e podem ser substituídos para fazer o que você quiser. A única outra diferença é queEquals
é virtual eoperator ==
não é.==
- você só pode sobrecarregá- lo.O problema é que o operador == em C # é uma chamada para um método estático (bem, talvez não tecnicamente, mas pode ser como tal) com base no tipo de tempo de compilação dos dois parâmetros. Quais são os tipos reais de tempo de execução desses objetos não importa.
Com base nesse tipo de tempo de compilação, o compilador determinará qual implementação
operator ==
usar. Pode usar o padrãoobject
implementação , pode usar uma das sobrecargas numéricas fornecidas pelo idioma ou pode ser uma implementação definida pelo usuário.Isso é diferente do VB, pois o VB não determina a implementação no momento da compilação. Ele espera até o tempo de execução e inspeciona os dois parâmetros que são dados para determinar qual implementação do
==
operador ele deve usar.Seu código contém valores booleanos, mas eles estão em variáveis que são do tipo
object
. Como a variável é do tipoobject
, o compilador C # usa aobject
implementação de==
, que compara as referências , não as instâncias do objeto. Como os valores booleanos são caixas, eles não têm a mesma referência, mesmo que seus valores sejam os mesmos.O código VB não se importa com o tipo da variável. Ele espera até o tempo de execução e, em seguida, verifica as duas variáveis, vê que elas são realmente do tipo booleano e, portanto, usa a
==
implementação do operador booleano . Essa implementação compara os valores dos booleanos, não suas referências (e os booleanos serão unboxed antes de chamar a chamada desse operador, portanto, uma comparação de referência nem faz mais sentido). Como os valores dos booleanos são os mesmos, ele retorna true.fonte
=
faz no VB para dizer com certeza.=
, juntamente com todos os outros operadores de comparação relacionais como<
,>=
, etc. , recebem tratamento especial quando ambos ou ambos os lados do operador estiveremObject
. Esse tratamento especial é feito para que os programadores do VB6, que estão acostumados a usar um tipo conhecidoVariant
no VB pré-.NET, possam fazer uso doObject
VB.Net da maneira que eles usavamVariant
antes.Option Strict On
, o VB=
é direcionado para o unboxing anObject
até que ele possa chegar a uma String ou numérica.