Pourquoi ne.ToString () sur une chaîne null cause une erreur null, when.ToString () fonctionne bien sur un int nul avec une valeur nulle?
selectedItem
a deux champs:
-
int? _cost
-
string _serialNumber
dans cet exemple, _cost
et _serialNumber
de selectedItem
sont tous deux nuls. Je lis à travers les champs selectedItem
via leurs propriétés, et je remplis les boîtes de textes avec leurs valeurs, quand...
TextBox1.Text = selectedItem.Cost.ToString(); //no error
TextBox2.Text = selectedItem.SerialNumber.ToString(); //error
je comprends que SerialNumber.ToString()
est redondant (parce qu'il est déjà une chaîne), mais je ne comprends pas pourquoi cela provoque cette exception:
Nullable objet doit avoir une valeur.
-
int? _cost
est nul, et n'a pas de valeur, mais il ne me donne pas l'exception. -
string _serialNumber
est nul, et n'a pas de valeur, pourtant il fait me donner l'exception.
This question touche à elle, le gars demande essentiellement la même chose, mais il n'y a pas de réponse désignée, et il n'explique pas non plus pourquoi une nullable int
? Par exemple, puis-je utiliser .ToString()
sur un int nul mais pas sur une chaîne nulle?
8 réponses
parce que string
type null
ne pointe vraiment à rien, il n'y a aucun objet dans la mémoire.
mais le type int?
(nullable) même avec la valeur fixée à null
indique toujours un objet.
si vous lisez" CLR via C# " de Jeffrey Richter, vous découvrirez que les types nulles ne sont que des classes de façade pour les types communs avec certaines logiques incapables afin de rendre le travail avec le DB null plus pratique.
Cochez la case msdn pour en savoir plus sur les types annulables.
Un Nullable<int>
est un struct
et ne peut pas vraiment être nulle. Donc un appel de méthode sur une structure" null " fonctionne toujours.
il existe un certain" compilateur magique "qui fait de _cost == null
une expression valide.
int?
n'est pas un objet en soi mais un objet Nullable<int>
.
ainsi , lorsque vous déclarez int? _Cost
, vous déclarez effectivement Nullable<int> _Cost
et la propriété de _Cost.Value
est undefined
et non l'objet _Cost
lui-même.
c'est en fait un sucre syntaxique d'utiliser
non nullable
types commeint
,bool
oudecimal
facilement.
selon MSDN :
la syntaxe
T?
est abrégée pourSystem.Nullable<T>
, oùT
est un type de valeur. Les deux formes sont interchangeables.
une chaîne de caractères est un type de référence, mais un int nul est un type de valeur. Voici une bonne discussion des différences http://www.albahari.com/valuevsreftypes.aspx .
le Nullable est en fait une structure exposant deux propriétés: HasValue et Value. Si vous faites cela, vous obtiendrez votre erreur:
int? i = null;
i.Value.ToString()
afin de vérifier si oui ou non votre int? a une valeur à laquelle vous pouvez accéder i.HasValue
ce que je pense que la raison est, quand le compilateur rencontre un type de données primitif il l'enveloppe, à son objet correspondant. L'appel de méthode toString() n'est qu'un appel indirect(envelopper puis appeler la méthode) ici et l'exception y est traitée. Alors que dans le cas de String, nous appelons directement la méthode. En pointant vers un nul, la méthode lance l'exception.
la raison est simple. int?
ou Nullable<int>
est un struct ou un type de valeur , il ne peut jamais être nul .
alors que se passe-t-il quand nous faisons:
int? _cost = null;
_cost
aura deux champs Value
et HasValue
, quand nous assignons null
à _cost
son drapeau HasValue
sera mis à false
et le champ Value
seraient assignés default(T)
dans le cas de int?
il serait 0
.
maintenant quand nous appelons ToString
sur _cost
, Nullable<T>
a une définition de surpassement de ToString
, qui si nous regardons référence de source fournie de Microsoft est mis en œuvre comme:
public override string ToString() {
return HasValue ? value.ToString() : "";
}
renvoie donc une chaîne vide, puisque _cost
est assigné null
.
vient maintenant le cas de string _serialNumber
. Étant string
il est un type de référence et il peut purement tenir null
. S'il contient null
, alors appeler ToString
produirait L'Exception de référence nulle comme prévu.
vous pouvez voir: types de valeurs et Types de référence - MSDN
TextBox2.Text = selectedItem.SerialNumber.ToString(); //error
yiels erreur parce qu'il appelle la fonction ToString() qui est membre de système.Chaîne . Cette fonction renvoie cette instance du système.Chaîne de caractères; aucune conversion réelle n'est effectuée. Aussi, String est un type de référence. Un type de référence contient un pointeur vers un autre emplacement mémoire qui contient les données.
TextBox1.Text = selectedItem.Cost.ToString(); //no error
ne produit aucune erreur car il appelle à la fonction ToString() qui est un membre du système .Entier . Cette fonction convertit la valeur numérique de cette instance en sa représentation équivalente de chaîne de caractères. Aussi, entier est un type de valeur. Un type de données est un type de valeur s'il détient les données dans sa propre allocation de mémoire.
le même nom de fonction ToString() mais exécute des tâches différentes.