IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

NullReferenceException avec des variables qui ont des valeurs


Sujet :

C#

  1. #1
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    2 863
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 2 863
    Par défaut NullReferenceException avec des variables qui ont des valeurs
    Bonjour tout le monde,

    Quand on a une NullReferenceException, d'habitude, c'est que quelque part sur la ligne, il existe une variable non instanciée, ou non initialisée, ou initialisée à Null, non ?

    Bon alors v'là-t-y pas que j'ai ça là-dessus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    C.init(strDate, (Rt["SysVal"] + "").ToString(), (Rt["DiaVal"] + "").ToString(), (Rt["PulVal"] + "").ToString(), (Rt["OxyVal"] + "").ToString(), Rt["commentaire"].ToString());
    C contient bien un objet de type
    ucTension, qui a une méthode void init acceptant six arguments chaînes de caractères, dont certains seront ensuite convertis en numérique ou date.

    strDate contient la chaîne formatée d'une date valide,
    Rt["SysVal"] vaut un nombre
    Rt["DiaVal"] vaut un nombre
    Rt["PulVal"] vaut un nombre
    Rt["OxyVal"] vaut un nombre
    Rt["commentaire"] est une chaîne de caractères.

    et je dis ça parce que j'ai lu les valeurs de chacun de ces éléments.

    J'ai ajouté une chaîne vide à chaque objet dont je tire ToString(), de façon que si ce qui est devant est nul, ce dont je tire ToString() n'est pas nul, vu qu'il y a déjà eu des échecs à dire que Null.ToString() vaut "null". Bon enfin en tout cas, vu que le résultat ne pouvait pas être converti en nombre. Je ne dis pas ça pour commentaire, pour lequel ToString() était du luxe.

    Du coup, là-dedans, qu'est-ce qui peut bien être nul ?

    J'aurais envie de dire l'erreur, mais bon ça c'est parce que c'est fatigant ce bazar.

  2. #2
    Modérateur
    Avatar de sevyc64
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    10 249
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 249
    Par défaut
    SI l'erreur est sur cette ligne et que pourtant tout est bon, l'erreur se produit sans doute à l'intérieur de la méthode Init sans y être interceptée et est donc propagée jusqu'à cet appel.

  3. #3
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    2 863
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 2 863
    Par défaut
    Bien vu !
    Dans le try...catch j'ai mis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    System.Diagnostics.Debug.Print(String.Format("{0} :\n SYS{1} DIA{2} PUL{3} OXY{4} \n" + 
    "commentaire : «{5}» \n(len(commentaire) = {6})\n(len(commentaire.trim())={7}\ncommentaire(trim) : «{8}»)", 
    strDate, (Rt["SysVal"] + "").ToString(), (Rt["DiaVal"] + "").ToString(), 
    (Rt["PulVal"] + "").ToString(), (Rt["OxyVal"] + "").ToString(), Rt["commentaire"].ToString(),
    Rt["commentaire"].ToString().Length.ToString(), 
    Rt["commentaire"].ToString().Trim().Length.ToString(), 
    Rt["commentaire"].ToString().Trim()));
    et c'est là que je vois apparaître "txbDateTime a été nul", ce qui s'avère exagérément optimiste, puisque, apparemment, txbDateTime a toutes chances d'être encore nul.

    Et ce d'autant plus que si dans init je lui mets

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
                MessageBox.Show("Début init");
                if(this == null)
                {
                    MessageBox.Show("Contrôle utilisateur nul");
                    return;
                }
                if(txbDateHeure == null)
                {
                    MessageBox.Show("Création de txbDateHeure");
                    txbDateHeure = new TextBox();
                    MessageBox.Show("Contrôle txbDateHeure créé");
                }
                if(txbDateHeure != null) 
                {
                    this.txbDateHeure.Text = dateheure;
                }
                else
                {
                    MessageBox.Show("Contrôle txbDateHeure toujours nul");
                    return;
                }
    alors je vois "Début init", puis plus aucun autre MessageBox, mais NullReferenceException.

    Du coup je n'en suis qu'au début d'une piste pour comprendre ce qui se passe.

    Tiens mais ... C'est vrai ça, si j'avance en pas à pas avec F11, il n'y aurait pas moyen de passer à l'intérieur de init, procédure public ?

  4. #4
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    2 863
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 2 863
    Par défaut
    Bon alors je remets à plat le formulaire, histoire d'y voir plus clair.
    À vrai dire, pour le moment l'objectif n'est pas atteint.

    Lorsque j'essaie d'ouvrir le formulaire dans l'éditeur de conception, impossible, ça m'affiche l'erreur "Impossible de charger la DLL 'Microsoft.Data.SqlClient.SNI.x64.dll': Le module spécifié est introuvable. (Exception de HRESULT : 0x8007007E) "

    (Il s'agit pourtant du nom d'un fichier présent dans bin\debug)

    Autant dire, de quoi ouvrir un autre fil.

    Ce projet est plus fatigant que prévu ...

    Dois-je comprendre qu'il faut réinstaller .Net ?

  5. #5
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    Qu'est-ce-qui t'autorise à penser que, par exemple, (Rt["SysVal"] + "").ToString() ne va pas se gameller lamentablement si la valeur renvoyée est nulle ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(txbDateHeure != null) 
    {
        this.txbDateHeure.Text = dateheure;
    }
    Est-ce-que txbDateHeure et this.txbDateHeure référencent bien la même variable ? Ou autrement dit, est-ce-qu'il n'y a pas une variable locale txbDateHeure qui masque la variable d'instance this.txbDateHeure ?

  6. #6
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    2 863
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 2 863
    Par défaut
    Ben ... Quelques tests.

    Fallait pas ?

    Possible, apparemment c'est carrément rien de moins que Sql Server qui s'est "gamellé lamentablement".

    Ça peut arriver que pour une raison ou pour une autre ça se plante, mais ce coup-là, dans ce projet, ça s'est "gamellé lamentablement".

    Tu penses que c'est à cause de cette requête ?
    Mince, avant ça avait fonctionné, pourtant ...

  7. #7
    Membre émérite
    Profil pro
    Développeur Web
    Inscrit en
    Février 2008
    Messages
    2 863
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Février 2008
    Messages : 2 863
    Par défaut
    Bonsoir,

    Bon vous savez quoi, comme j'ai la nette impression de vous avoir posé quelques colles avec mon application, j'ai tout refait et ça marche. Seul truc, l'application n'a plus le même nom, enfin ça, normalement, ça devrait être gérable.

    Donc ... si je ne m'abuse les questions n'ont pas trouvé de réponses, mais j'ai trouvé un autre chemin et ça tourne, donc je vais cliquer sur Résolu.

    Je n'ai pas osé mettre une image sur le bouton.

    Avant d'attaquer la sortie PDF je ferai quelques copies, histoire d'arrêter mes bêtises.

    ***

    Ah, euh, question subsidiaire ...

    Comme avantage supplémentaire d'avoir recommencé depuis le début, il n'y a plus de manœuvres que je dois recommencer à chaque compilation, comme par exemple déclarer une DataGridView, supprimer un fichier de ressources ...

    Honnêtement, je suis assez flou sur ce qui a pu se passer à ce niveau.

    Quelqu'un aurait-il une ou des hypothèse(s) ?

  8. #8
    Membre Expert
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 941
    Par défaut
    J'ai fait quelques recherches et il s'avère que tu avais raison pour ??? + "". En gros, quand il y a une chaîne de caractères dans une suite d'opérateurs +, c'est transformé en concaténation de la représentation textuelle des différents éléments (c'est-à-dire un ToString() des objets concrets et la chaîne vide pour une référence null). Donc null + "" ne lève pas d'exception et résulte en "" ; "hello" + 3 + null + 4 + "world" donne "hello34world". Par contre, puisque tu es certain d'avoir une chaîne après Rt["SysVal"] + "", l'appel à ToString() est caduque.

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo