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?

65
demandé sur Community 2012-07-12 11:20:28

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.

88
répondu Johnny_D 2012-07-18 17:29:17

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.

31
répondu Hans Kesting 2012-07-12 07:24:05

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 comme int , bool ou decimal facilement.

selon MSDN :

la syntaxe T? est abrégée pour System.Nullable<T> , où T est un type de valeur. Les deux formes sont interchangeables.

14
répondu Asif Mushtaq 2015-05-19 11:09:02

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 .

4
répondu Tom Highfield 2012-07-12 07:31:07

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

2
répondu Corné Hogerheijde 2012-07-12 12:14:11

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.

1
répondu Sashi Kant 2012-07-12 07:30:48

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

1
répondu Habib 2017-04-23 08:41:13
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.

de la Chaîne.Méthode ToString

Int32.Méthode ToString

types de valeurs et types de référence

0
répondu Angkor Wat 2012-07-12 12:05:17