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 croyance malheureuse selon laquelle 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 test d'égalité et d'inégalité devraient être censées donner le même résultat, malgré le fait que différentes sémantiques sont utiles dans des circonstances différentes. Par exemple, d'un point de vue arithmétique, il est utile de pouvoir avoir des Decimal
qui diffèrent seulement par le nombre de zéros en fin de comparaison comme égaux. De même pour des valeurs de double
comme zéro positif et zéro négatif. En revanche, d'un point de vue de mise en cache ou d'internement, de telles sémantiques peuvent être mortelles. Supposons, par exemple, que l'on ait un Dictionary
tel que myDict[someDecimal]
devrait être égal à someDecimal.ToString()
. Un tel objet semblerait raisonnable si l'on avait de nombreuses valeurs de Decimal
que l'on voulait convertir en chaîne et que l'on attendait qu'il y ait de nombreuses duplications. Malheureusement, si l'on utilisait une telle mise en cache 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".
En revenant à la question en cours, il existe plus d'une façon raisonnable de comparer des objets nuls pour l'égalité. C# adopte le point de vue que son opérateur ==
doit refléter le comportement de Equals
. VB.NET adopte le point de vue que son comportement devrait refléter celui de certains autres langages, puisque quiconque veut le comportement de Equals
pourrait utiliser Equals
. En un sens, la bonne solution serait d'avoir une construction "if" à trois voies, et exiger que si l'expression conditionnelle retourne un résultat à trois valeurs, le code doit spécifier ce qui devrait se produire dans le cas de null
. Comme cela n'est pas une option avec les langues telles qu'elles sont, la meilleure alternative est simplement d'apprendre comment fonctionnent différentes langues et de reconnaître qu'elles ne sont pas identiques.
Accessoirement, l'opérateur "Is" de Visual Basic, qui fait défaut en C, peut être utilisé pour tester si un objet nul est effectivement nul. Bien que l'on puisse raisonnablement se demander si un test if
devrait accepter un Boolean?
, le fait que les opérateurs de comparaison normaux retournent Boolean?
plutôt que Boolean
lorsqu'ils sont invoqués sur des types nullables est une fonctionnalité utile. Par ailleurs, en VB.NET, si l'on tente d'utiliser l'opérateur d'égalité au lieu de Is
, on obtiendra un avertissement indiquant que le résultat de la comparaison sera toujours Nothing
, et on devrait utiliser Is
si l'on veut tester si quelque chose est nul.
23 votes
C'est terrifiant.
8 votes
Je crois que
default(decimal?)
renvoie 0, nonnull
.7 votes
@RyanFrame NON. Puisqu'il s'agit de types nullable, cela renvoie
null
1 votes
@RyanFrame Même si c'était le cas,
0 != 5
tout commenull != 5
, n'est-ce pas?0 votes
Oui... donc je n'ai aucune idée.
2 votes
Possible duplicate de C# vs VB.NET - Gestion des Structures null
0 votes
X est null en c# et Nothing en vb - c'est pourquoi je ne comprends pas le comportement différent
4 votes
Oh ouais... c'est vrai... en VB
If
les conditions ne nécessitent pas d'être évaluées comme un booléen... pffff ÉDITION: AinsiNothing <> Anything = Nothing
ce qui entraîne leIf
à prendre la route négative/else.2 votes
@Défaut Parce que j'avais toujours cru que null et rien étaient équivalents, j'ai pensé que c'était une façon intelligente de souligner que ce n'est pas le cas, d'où le +1
13 votes
@JMK: Null, Nothing et Empty sont en fait tous subtilement différents. Si ils étaient tous les mêmes alors vous n'auriez pas besoin des trois.
1 votes
@EricLippert Très intéressant, vos articles de blog sur le sujet sont également formidables, merci!
0 votes
Crickey, VB me terrifie parfois...