Ho fatto qualche ricerca su questo usando diversi metodi per assegnare valori a un int nullabile. Ecco cosa è successo quando ho fatto varie cose. Dovrebbe chiarire cosa sta succedendo. Ricorda: Nullable<something>
o la stenografia something?
è una struttura per la quale il compilatore sembra fare molto lavoro per farci usare con null come se fosse una classe.
Come si vedrà di seguito, SomeNullable == null
e SomeNullable.HasValue
sarà sempre restituire un atteso vero o falso. Anche se non dimostrato di seguito, SomeNullable == 3
è valido anche (supponendo che SomeNullable sia un int?
).
Mentre SomeNullable.Value
ci viene assegnato un errore di runtime se assegnato null
a SomeNullable
. Questo è in effetti l'unico caso in cui nullable potrebbe causarci un problema, grazie a una combinazione di operatori sovraccarichi, sovraccarichiobject.Equals(obj)
metodo, ottimizzazione del compilatore e business delle scimmie.
Ecco una descrizione di alcuni codici che ho eseguito e quale output ha prodotto nelle etichette:
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, proviamo il prossimo metodo di inizializzazione:
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.")
Lo stesso di prima. Tieni presente che l'inizializzazione con int? val = new int?(null);
, con null passato al costruttore, avrebbe prodotto un errore di tempo COMPILE, poiché il valore VALUE dell'oggetto nullable NON è nullable. È solo l'oggetto wrapper stesso che può essere uguale a null.
Allo stesso modo, avremmo un errore di compilazione da:
int? val = new int?();
val.Value = null;
per non parlare del fatto che val.Value
è una proprietà di sola lettura, il che significa che non possiamo nemmeno usare qualcosa come:
val.Value = 3;
ma ancora, gli operatori di conversione implicita sovraccarica polimorfa ci permettono di fare:
val = 3;
Non c'è bisogno di preoccuparsi di polisomica, qualunque cosa accada, purché funzioni bene? :)