J'ai fait quelques recherches à ce sujet en utilisant différentes méthodes pour assigner des valeurs à un int nullable. Voici ce qui s'est passé lorsque j'ai fait différentes choses. Cela devrait clarifier ce qui se passe. N'oubliez pas : Nullable<something>
ou l'abréviation something?
est une structure pour laquelle le compilateur semble faire beaucoup de travail pour nous permettre de l'utiliser avec null comme s'il s'agissait d'une classe.
Comme vous le verrez ci-dessous, SomeNullable == null
y SomeNullable.HasValue
renverra toujours un vrai ou un faux. Bien que cela ne soit pas démontré ci-dessous, SomeNullable == 3
est également valide (en supposant que SomeNullable est un int?
).
Tandis que SomeNullable.Value
Nous obtenons une erreur d'exécution si nous avons assigné null
a SomeNullable
. C'est en fait le seul cas où les nullables pourraient nous poser problème, grâce à une combinaison d'opérateurs surchargés, de object.Equals(obj)
et l'optimisation du compilateur et les affaires de singe.
Voici une description d'un code que j'ai exécuté et des résultats qu'il a produits sous forme d'étiquettes :
int? val = null;
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Ok, essayons la méthode d'initialisation suivante :
int? val = new int?();
lbl_Val.Text = val.ToString(); //Produced an empty string.
lbl_ValVal.Text = val.Value.ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValEqNull.Text = (val == null).ToString(); //Produced "True" (without the quotes)
lbl_ValNEqNull.Text = (val != null).ToString(); //Produced "False"
lbl_ValHasVal.Text = val.HasValue.ToString(); //Produced "False"
lbl_NValHasVal.Text = (!(val.HasValue)).ToString(); //Produced "True"
lbl_ValValEqNull.Text = (val.Value == null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
lbl_ValValNEqNull.Text = (val.Value != null).ToString(); //Produced a runtime error. ("Nullable object must have a value.")
Tout comme auparavant. Gardez à l'esprit que l'initialisation avec int? val = new int?(null);
avec null passé au constructeur, aurait produit une erreur de temps de COMPILATION, puisque la VALEUR de l'objet nullable n'est PAS nullable. Ce n'est que l'objet enveloppant lui-même qui peut être égal à null.
De même, nous obtiendrions une erreur au moment de la compilation à partir de :
int? val = new int?();
val.Value = null;
sans oublier que val.Value
est de toute façon une propriété en lecture seule, ce qui signifie que nous ne pouvons même pas utiliser quelque chose comme :
val.Value = 3;
mais là encore, les opérateurs de conversion implicites surchargés polymorphes nous permettent de le faire :
val = 3;
Il n'y a pas lieu de s'inquiéter des polysomnies, du moment qu'elles fonctionnent bien :)
10 votes
J'ai posé une question similaire... j'ai obtenu de bonnes réponses : stackoverflow.com/questions/633286/
3 votes
Personnellement J'utiliserais
HasValue
car je pense que les mots ont tendance à être plus lisibles que les symboles. Mais tout dépend de vous et de ce qui correspond à votre style.1 votes
.HasValue
est plus logique car il indique que le type est de typeT?
plutôt qu'un type qui peut être nullable comme les chaînes de caractères.