J'ai fait quelques recherches à ce sujet en utilisant différentes méthodes pour attribuer des valeurs à un entier nullable. Voici ce qui s'est passé lorsque j'ai fait diverses choses. Devrait clarifier ce qui se passe. Gardez à l'esprit: Nullable<something>
ou le raccourci something?
est une structure pour laquelle le compilateur semble faire beaucoup de travail pour nous permettre d'utiliser avec null comme s'il s'agissait d'une classe.
Comme vous le verrez ci-dessous, SomeNullable == null
et SomeNullable.HasValue
retournera toujours un vrai ou un faux attendu. Bien que cela ne soit pas démontré ci-dessous, il SomeNullable == 3
est également valide (en supposant que SomeNullable est un int?
).
Alors que SomeNullable.Value
nous obtient une erreur d'exécution si nous avons attribué null
à SomeNullable
. C'est en fait le seul cas où nullables pourrait nous poser problème, grâce à une combinaison d'opérateurs surchargés, surchargésobject.Equals(obj)
méthode, et optimisation du compilateur et entreprise de singe.
Voici une description du code que j'ai exécuté et de la sortie qu'il a produite dans les é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 prochaine méthode d'initialisation:
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 avant. 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, car la valeur de l'objet nullable n'est PAS nullable. Seul l'objet wrapper lui-même peut être égal à null.
De même, nous obtiendrions une erreur de temps de compilation de:
int? val = new int?();
val.Value = null;
sans compter que val.Value
c'est une propriété en lecture seule de toute façon, ce qui signifie que nous ne pouvons même pas utiliser quelque chose comme:
val.Value = 3;
mais encore une fois, les opérateurs de conversion implicites surchargés polymorphes nous permettent de faire:
val = 3;
Pas besoin de s'inquiéter de tout ce qui peut arriver, tant qu'il fonctionne bien? :)