Le problème observé ici est un cas particulier d'un problème plus général, à savoir que le nombre de définitions différentes de l'égalité qui peuvent être utiles dans au moins certaines circonstances dépasse le nombre de moyens couramment disponibles pour les exprimer. Ce problème est dans certains cas aggravé par une malheureuse croyance qu'il est déroutant d'avoir différents moyens de tester l'égalité donnant des résultats différents, et une telle confusion pourrait être évitée en faisant en sorte que les différentes formes d'égalité donnent les mêmes résultats chaque fois que possible.
En réalité, la cause fondamentale de la confusion est une croyance erronée selon laquelle les différentes formes de tests d'égalité et d'inégalité devraient produire le même résultat, même si des sémantiques différentes sont utiles dans des circonstances différentes. Par exemple, d'un point de vue arithmétique, il est utile de pouvoir Decimal
comparer les valeurs qui ne diffèrent que par le nombre de zéros à la fin. De même pour des double
valeurs telles que zéro positif et zéro négatif. D'un autre côté, du point de vue de la mise en cache ou de l'internement, une telle sémantique peut être mortelle. Supposons, par exemple, que l'on ait un Dictionary<Decimal, String>
tel qui myDict[someDecimal]
devrait égaler someDecimal.ToString()
. Un tel objet semblerait raisonnable si l'on avait plusieursDecimal
valeurs que l'on voulait convertir en chaîne et s'attendait à ce qu'il y ait de nombreux doublons. Malheureusement, si une telle mise en cache était utilisée pour convertir 12,3 m et 12,40 m, suivis de 12,30 m et 12,4 m, ces dernières valeurs donneraient «12,3» et «12,40» au lieu de «12,30» et «12,4».
Pour en revenir à la question à l'étude, il existe plus d'une manière sensée de comparer des objets Nullable pour l'égalité. C # part du principe que son ==
opérateur doit refléter le comportement de Equals
. VB.NET part du principe que son comportement doit refléter celui de certains autres langages, car quiconque souhaite le Equals
comportement peut l'utiliser Equals
. Dans un certain sens, la bonne solution serait d'avoir une construction "si" à trois voies et d'exiger que si l'expression conditionnelle renvoie un résultat à trois valeurs, le code doit spécifier ce qui doit se passer dans le null
cas. Étant donné que ce n'est pas une option avec les langues telles qu'elles sont, la meilleure alternative consiste simplement à apprendre comment les différentes langues fonctionnent et à reconnaître qu'elles ne sont pas les mêmes.
Incidemment, l'opérateur "Est" de Visual Basic, qui fait défaut dans C, peut être utilisé pour tester si un objet Nullable est, en fait, null. Bien que l'on puisse raisonnablement se demander si un if
test devrait accepter a Boolean?
, avoir les opérateurs de comparaison normaux retournent Boolean?
plutôt que Boolean
lorsqu'ils sont appelés sur des types Nullable est une fonctionnalité utile. Incidemment, dans VB.NET, si l'on tente d'utiliser l'opérateur d'égalité plutôt que Is
, on obtiendra un avertissement que le résultat de la comparaison sera toujours Nothing
, et on devrait l'utiliser Is
si l'on veut tester si quelque chose est nul.