J'ai deux objets en C # et je ne sais pas si c'est booléen ou tout autre type. Cependant, lorsque j'essaye de comparer ces C #, je ne donne pas la bonne réponse. J'ai essayé le même code avec VB.NET et ça l'a fait!
Quelqu'un peut-il me dire comment résoudre ce problème s'il existe une solution?
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
la source
la source
a.Equals(b)
?a
vous obtenez la boxe et créez une boîte contenanttrue
. Lorsque vous attribuez àb
vous obtenez une autre boîte contenant égalementtrue
. Lorsque vous compareza
etb
, comme les deux sont de type à la compilationobject
, vous appelez la surchargeoperator ==(object, object)
définie par la spécification du langage C #. Cette surcharge vérifie si les références vont au même objet. Puisque vous avez deux boîtes, le résultat estfalse
, et l'instruction "sous" votreif
ne fonctionnera pas. Pour mieux comprendre cela, essayez de modifier l'attribution deb
à ceci:object b = a;
Vous n'avez plus qu'une seule case.Réponses:
En C #, l'
==
opérateur (lorsqu'il est appliqué aux expressions de type référence) effectue une vérification d'égalité de référence à moins qu'il ne soit surchargé . Vous comparez deux références qui sont le résultat de conversions de boxe, donc ce sont des références distinctes.EDIT: Avec les types qui surchargent le
==
, vous pouvez obtenir un comportement différent - mais cela est basé sur le type au moment de la compilation des expressions. Par exemple,string
fournit==(string, string
):Ici, la première comparaison utilise l'opérateur surchargé, mais la seconde utilise la comparaison de référence "par défaut".
En VB, l'
=
opérateur fait beaucoup plus de travail - ce n'est même pas simplement équivalent à utiliserobject.Equals(x, y)
, comme des choses commeOption Compare
peuvent affecter la façon dont le texte est comparé.Fondamentalement, les opérateurs ne fonctionnent pas de la même manière et ne sont pas destinés à fonctionner de la même manière.
la source
=
qui se passait dans VB, mais les spécifications ne sont pas très claires.bool == bool
comparaison.En plus de la réponse de Jon qui explique le côté C # des choses, voici ce que fait VB:
Dans VB with
Option Strict On
, une comparaison via teste=
toujours l' égalité des valeurs et jamais l'égalité des références. En fait, votre code ne se compile même pas une fois que vous basculezOption Strict On
carSystem.Object
il ne définit pas de fichierOperator=
. Vous devriez toujours avoir cette option activée, elle détecte les bogues plus efficacement qu'un piège à mouches venus (bien que dans votre cas particulier, ce comportement laxiste fasse réellement la bonne chose). 1En fait, avec
Option Strict On
, VB se comporte encore plus stricte que C #: en C #,a == b
soit déclenche un appel à,SomeType.operator==(a, b)
soit, si cela n'existe pas, appelle la comparaison d'égalité de référence (ce qui équivaut à appelerobject.ReferenceEquals(a, b)
).En VB par contre, la comparaison invoque
a = b
toujours l'opérateur d'égalité. 2 Si vous souhaitez utiliser la comparaison d'égalité de référence, vous devez utilisera Is b
(qui est, encore une fois, le même queObject.ReferenceEquals(a, b)
).1) Voici une bonne indication des raisons pour lesquelles utiliser
Option Strict Off
est une mauvaise idée: j'utilise VB.NET depuis près d'une décennie, depuis la sortie officielle de .NET jusqu'à il y a quelques années, et je n'ai absolument aucune idée de cea = b
que cela signifieOption Strict Off
. Il fait une sorte de comparaison d'égalité, mais ce qui se passe exactement et pourquoi, aucune idée. C'est plus complexe que la fonctionnalité de C #dynamic
, cependant (car cela repose sur une API bien documentée). Voici ce que dit le MSDN:2) Jon a mentionné une exception, les chaînes, où la comparaison d'égalité fait encore plus de choses pour des raisons de compatibilité ascendante.
la source
Option Strict On
doit être considéré comme une infraction pénale ...Les instances d'objet ne sont pas comparées à l'opérateur "==". Vous devez utiliser la méthode «égal». Avec l'opérateur "==", comparez des références, pas des objets.
Essaye ça:
Résultats:
Maintenant, essayez ceci:
Résultats:
la source
operator ==
. Si vous remplacez cet opérateur et qu'il n'est pas égal, votre sortie serait inversée. Il n'y a rien d'inhérent à la comparaison de référencesoperator ==
et rien d'inhérent à la comparaison de valeurs dansEquals
. Ce ne sont que deux façons de déterminer l'égalité; les deux ont des implémentations par défaut d'une comparaison de référence, et les deux peuvent être remplacés pour faire ce que vous voulez qu'ils fassent. La seule autre différence est queEquals
c'est virtuel etoperator ==
ne l'est pas.==
- vous ne pouvez que le surcharger .Le problème est que l'opérateur == en C # est un appel à une méthode statique (enfin, peut-être pas techniquement, mais cela peut être considéré comme tel) basé sur le type de compilation des deux paramètres. Les types d'exécution réels de ces objets n'ont pas d'importance.
En fonction de ce type de compilation, le compilateur déterminera quelle implémentation
operator ==
utiliser. Il peut utiliser l'object
implémentation par défaut , il peut utiliser l'une des surcharges numériques fournies par le langage, ou il peut s'agir d'une implémentation définie par l'utilisateur.Ceci est différent de VB en ce que VB ne détermine pas l'implémentation au moment de la compilation. Il attend l'exécution et inspecte les deux paramètres qui lui sont donnés pour déterminer quelle implémentation de l'
==
opérateur il doit utiliser.Votre code contient des valeurs booléennes, mais elles sont dans des variables de type
object
. Étant donné que la variable est de typeobject
, le compilateur C # utilise l'object
implémentation de==
, qui compare les références , et non les instances d'objet. Puisque les valeurs booléennes sont des boîtes, elles n'ont pas la même référence, même si leurs valeurs sont les mêmes.Le code VB ne se soucie pas du type de la variable. Il attend l'exécution, puis vérifie les deux variables, voit qu'elles sont en fait de type booléen et utilise donc l'
==
implémentation de l'opérateur booléen . Cette implémentation compare les valeurs des booléens, pas leurs références (et les booléens seront déballés avant d'appeler cet opérateur, donc une comparaison de références n'a même plus de sens). Étant donné que les valeurs des booléens sont les mêmes, il renvoie true.la source
=
fait VB pour être sûr.=
, ainsi que tous les autres opérateurs de comparaison relationnels tels que<
,>=
, etc. , reçoivent un traitement spécial lorsque les deux côtés de l'opérateur ou l'un ou l'autre le sontObject
. Ce traitement spécial est fait pour que les programmeurs VB6, qui sont habitués à utiliser un type connu sous le nomVariant
de pre-.NET VB, puissent utiliserObject
dans VB.Net de la manière qu'ils ont utiliséeVariant
auparavant.Option Strict On
, VB=
est biaisé vers le déballage etObject
jusqu'à ce qu'il puisse atteindre une chaîne ou un numérique.