152 votes

Pourquoi c# échoue à comparer deux objet types entre eux mais doesn VB ' t ?

J’ai deux objets en langage c# et ne sais pas si c’est Boolean ou tout autre type. Cependant quand j’essaie de comparer celles c# ne parvient pas à donner la bonne réponse. J’ai essayé le même code avec VB.NET et qui l’a fait !

Quelqu'un peut-il me dire comment résoudre ce problème, s’il y a une solution ?

C# :

VB.NET :

167voto

Jon Skeet Points 692016

En C#, == opérateur (lorsqu'il est appliqué à type de référence expressions) effectue une référence de contrôle d'égalité, sauf si elle est surchargée. Vous êtes de la comparaison de deux références qui sont le résultat de la boxe conversions, donc, ce sont des références distinctes.

EDIT: Avec des types qui surcharge l' ==, vous pouvez obtenir des comportements différents - mais qui est basée sur la compilation de type des expressions. Par exemple, string fournit ==(string, string):

string x = new string("foo".ToCharArray());
string y = new string("foo".ToCharArray());
Console.WriteLine(x == y); // True
Console.WriteLine((object) x == (object) y); // False

Ici, la première comparaison, est l'aide de l'opérateur surchargé, mais la seconde est d'utiliser le "par défaut" référence de comparaison.

En VB, l' = opérateur ne prend beaucoup plus de travail - il n'est même pas juste équivalent à l'utilisation de object.Equals(x, y), que des choses comme Option Compare peut affecter la façon dont le texte est comparé.

Fondamentalement, les opérateurs ne fonctionnent pas de la même façon et ne sont pas destinés à fonctionner de la même façon.

79voto

Konrad Rudolph Points 231505

En plus Jon réponse qui explique le C#, côté des choses, voici ce que VB n':

Dans visual basic avec Option Strict On, une comparaison via = toujours des tests de valeur de l'égalité et de jamais de référence à l'égalité. En fait, votre code n'a même pas compiler une fois que vous passez Option Strict On car System.Object ne définit pas un Operator=. Vous devriez toujours avoir cette option, il attrape les bugs de manière plus efficace qu'un venus flytrap (bien que dans votre cas particulier, ce laxisme ne fait la bonne chose).1

En fait, avec Option Strict On, VB se comporte de façon encore plus stricte que celle de C#: C#, a == b soit déclenche un appel à SomeType.operator==(a, b) ou, si cela n'existe pas, appelle de référence de la comparaison d'égalité (ce qui est équivalent à l'appel de object.ReferenceEquals(a, b)).

En VB d'autre part, la comparaison a = b toujours invoque l'opérateur d'égalité.2 Si vous souhaitez utiliser la référence de comparaison d'égalité, vous devez utiliser a Is b (ce qui est, encore une fois, le même que l' Object.ReferenceEquals(a, b)).


1) Voici une bonne indication pourquoi l'utilisation d' Option Strict Off est une mauvaise idée: j'ai utilisé VB.NET pour près d'une décennie avant .NET version officielle jusqu'à il y a quelques années, et j'ai absolument aucune idée de ce qu' a = b avec Option Strict Off. Il fait ce genre de comparaison d'égalité, mais qu'est-ce qui se passe et pourquoi, aucune idée. C'est plus complexe que le C#' dynamic fonctionnalité, cependant (car qui s'appuie sur une API documentée). Voici ce que le MSDN dit:

Parce qu' Option Strict On offre typage fort, empêche involontaire conversions de type avec perte de données, il interdit la liaison tardive, et améliore les performances, son utilisation est fortement recommandée.

2) Jon a mentionné une exception près, les cordes, où l'égalité comparaison n'des choses un peu plus pour des raisons de rétro-compatibilité.

4voto

Lobo Points 1478

Instances d’objet ne sont pas comparées avec l’opérateur « == ». Vous devez pour utiliser la méthode « égale ». Avec « == » opérateur Comparez les références, pas d’objets.

Essayez ceci :

Résultats :

Maintenant, essayez ceci :

Résultats :

3voto

Servy Points 93720

Le problème est que l'opérateur == en C# est un appel à une méthode statique (bien, peut-être pas techniquement, mais il peut être bien comme tel) basé sur le moment de la compilation, le type de ces deux paramètres. Quel est le véritable moteur d'exécution types de ces objets n'a pas d'importance.

Basé sur ce moment de la compilation, le type, le compilateur de déterminer ce que la mise en œuvre de l' operator == à utiliser. Il peut utiliser la valeur par défaut object mise en œuvre, il peut utiliser l'un des numériques surcharges prévues par la langue, ou il pourrait être définis par l'utilisateur mise en œuvre.

Ceci est différent de la VB dans que VB n'est pas de déterminer la mise en œuvre au moment de la compilation. Il attend jusqu'à ce moment de l'exécution et inspecte les deux paramètres qu'il est donné afin de déterminer lesquelles la mise en œuvre de l' == opérateur, il doit utiliser.

Votre code contient des valeurs booléennes, mais ils sont dans des variables de type object. Parce que la variable est de type object, le compilateur C# utiliser l' object de la mise en œuvre de l' ==, qui compare les références, pas les instances d'objet. Depuis les valeurs booléennes sont des boîtes, ils 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 de ce type de la variable. Il attend jusqu'à ce que l'exécution, puis vérifie les deux variables, voit qu'ils sont en fait à la fois de type booléen, et utilise donc le booléen == de l'opérateur de la mise en œuvre. Que la mise en œuvre de comparer les valeurs de la booléens, les pas de leurs références (et les booléens sera "unboxed" avant d'appeler l'appel de l'opérateur, donc une référence de comparaison n'a même pas de sens). Parce que les valeurs de la booléens sont les mêmes, il renvoie la valeur true.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X