Qu'est-ce que NullReferenceException ? La référence d'objet n'est pas définie à une instance d'un objet
Par : mwatson
| 5 mars 2021
"La référence d'objet n'est pas définie à une instance d'un objet." Jetez la première pierre à ceux qui n'ont jamais lutté avec ce message d'erreur lorsqu'ils étaient un programmeur C#/.NET débutant.
Ce message d'erreur infâme et redouté se produit lorsque vous obtenez une NullReferenceException. Cette exception est levée lorsque vous essayez d'accéder à un membre (par exemple, une méthode ou une propriété) sur une variable qui contient actuellement une référence nulle.
Mais qu'est-ce qu'une référence nulle ? Que sont les "références" en premier lieu ? Comment pouvez-vous empêcher l'exception NullReferenceException de se produire dans votre code ? C'est ce que nous allons couvrir dans le post d'aujourd'hui.
Nous allons commencer par les fondamentaux, en donnant une brève explication des références en C#/.NET. Après cela, vous apprendrez ce que sont les références nulles. À ce stade, vous êtes à mi-chemin pour voir l'ensemble de l'image.
Après cette série de définitions théoriques, nous aborderons des questions plus pratiques, vous apprenant comment éviter NullReferenceException dans la pratique. Creusons.
Que sont les références ?
Nous savons déjà que NullReferenceException est causée par une référence nulle. Mais qu'est-ce qu'une référence nulle ? En quoi diffère-t-elle d'une référence non nulle ?
Dans .NET, vous pouvez diviser les types de données en deux catégories : les types de valeur et les types de référence. Si vous avez une variable de type valeur, elle stocke la valeur elle-même. Les variables de type référence, en revanche, ne contiennent pas la valeur elle-même. Ils détiennent une référence qui indique où l'objet vit dans la mémoire.
Si cela vous aide à mieux le visualiser, vous pouvez considérer une référence comme un lien pointant vers une page Web ou un raccourci pointant vers un fichier sur votre ordinateur. Les types tels que int (et les autres types primitifs numériques), DateTime et boolean sont des types valeur. Autrement dit, les structures sont des types valeur. Les classes sont des types de référence.
Ainsi, une référence est ce que contient une variable d'un type référence. Ces variables peuvent pointer vers "rien", cependant, et c'est ce que nous appelons une référence nulle : une référence qui ne pointe vers aucun objet. Lorsque vous essayez d'appeler une méthode ou un autre membre sur ladite variable, vous obtenez l'exception NullReferenceException.
<< Les erreurs de référence nulle sont responsables d'un bon pourcentage de tous les bogues de l'application.>>
Comprendre l'exception NullReferenceException
Les erreurs de référence nulle sont responsables d'un bon pourcentage de tousbogues d'application. Ce sont généralement des problèmes très simples causés par l'absence d'ajout de logique supplémentaire pour s'assurer que les objets ont des valeurs valides avant de les utiliser. Voici quelques façons d'éviter NullReferenceException.
Le code suivant lèvera une NullReferenceException si la variable "texte" transmise est nulle. Vous ne pouvez pas appeler ToUpper() sur une chaîne nulle.
public void MyMethod (chaîne de texte)
{
// Lève une exception si text == null
if (text.ToUpper() == "Hello World")
{
//faire quelque chose
}
}
Vous pouvez également avoir des exceptions de référence null car tout type d'objet est null.Par exemple, dans le code ci-dessous, l'objet SqlCommand n'est jamais initialisé. Ne pas exécuter une requête SQL serait un sérieux problème pour votre application. Une chaîne nulle peut être quelque chose que vous ignorez et passez à autre chose. D'autres fois, comme avec SqlCommand, cela pourrait être un problème fatal que vous ne voulez pas ignorer.
Commande SqlCommand = null ;
//Exception! La référence d'objet n'est pas définie à une instance d'un objet
command.ExecuteNonQuery();
Utiliser l'opérateur conditionnel Null pour éviter les exceptions NullReference
L'un des meilleurs nouveaux ajouts à C # était leopérateur conditionnel nul. Au lieu d'avoir une quantité folle de vérifications de type "variable != null", vous pouvez utiliser le "?" et votre code court-circuitera et renverra null au lieu de lever l'exception. Cela aura plus de sens avec quelques exemples ci-dessous :
text?.ToUpper(); // de l'exemple précédent, renverrait null
int? longueur = listeclients?.Longueur ; // null si listeclient est nul
Client d'abord = listeclients ?[0] ; // null si listeclient est nul
int? count = listeclients?[0]?.Commandes?.Count(); // null si customerList, le premier client ou Orders est null
Utiliser la coalescence nulle pour éviter les exceptions NullReferenceExceptions
Une autre grande fonctionnalité estfusion nulle, qui est le "??" opérateur. Cela fonctionne très bien pour fournir une valeur par défaut pour une variable nulle. Cela fonctionne avec tous les types de données nullables.
Le code suivant lève une exception sans la coalescence nulle. Ajouter "?? new List
Liste
foreach (valeur var dans les valeurs ?? nouvelle liste
{
Console.WriteLine(valeur);
}
Exemples simples de valeurs nulles causant des problèmes
Certaines des causes les plus courantes sont les paramètres, les appels de base de données ou les appels de type API qui ne renvoient pas les valeurs attendues. Par exemple, vous ajoutez un nouveau champ à votre base de données et ne remplissez pas les valeurs par défaut pour chaque enregistrement. Les enregistrements sont interrogés au hasard et le code ne tient pas compte de ce nouveau champ est nul. KA-BOOM : la référence d'objet n'est pas définie sur une instance d'un objet.
La règle d'or de la programmation
Pendant des années, j'ai eu un dicton que je dis tout le temps à mon équipe. C'est ce que j'appelle la règle d'or de la programmation. Je pense que chaque nouveau programmeur a besoin d'un tatouage qui le dit.
"Si ça peut être nul, ça sera nul"
La bonne nouvelle est que de nombreuses erreurs de référence nulles peuvent être évitées en ajoutant une logique et un code supplémentaires pour s'assurer que les objets ne sont pas nuls avant d'essayer de les utiliser.Les développeurs doivent toujours supposer que tout est invalide et être très défensifs dans leur code.Imaginez que chaque appel de base de données échoue, chaque champ contiendra des données erronées. Bienmeilleures pratiques de gestion des exceptionssont critiques.
Conseils pour éviter les exceptions de référence nulle
1. Initialisez les variables avec des valeurs valides.
2. Si une variable peut être nulle, vérifiez-la et gérez-la de manière appropriée
3. Utilisez le "?" opérateur sur les méthodes lorsque cela est possible. stringvar?.ToUpper();
4. Utilisez des outils comme Resharper pour aider à signaler les exceptions de référence nulles potentielles
Éviter NullReferenceException avec les types Nullable de C# 8.0
L'une des principales causes de bogues avec une référence nulle est le fait qu'en C, chaque objet de type référence peut être nul, tout le temps. Et si vous, le développeur, aviez le pouvoir de dire : "Je veux que cette chaîne ne soit pas nulle, jamais" ? Mieux encore, que se passerait-il si cette décision était appliquée par le compilateur lui-même, vous empêchant ainsi que d'autres développeurs d'attribuer accidentellement null à ladite variable ? Ça a l'air sympa ? Bonne nouvelle donc : il s'agit d'une véritable fonctionnalité de la huitième version de C# appelée, sans surprise, les types nullables.
<< La fonctionnalité fonctionne de manière ingénieuse et puissante.>>
La fonctionnalité fonctionne de manière ingénieuse et puissante. Il redéfinit les types de référence comme étant non-nullable par défaut, comme beaucoup soutiennent qu'ils auraient dû l'être depuis le début. Ensuite, il ajoute un nouveau type de syntaxe qui vous permet de définir des variables nullables (ce n'est pas vraiment nouveau, cependant, car c'est la même syntaxe qui est utilisée depuis plusieurs années pour les types de valeurs nullables.)
Pour mieux comprendre, regardez l'exemple suivant :
statique int Ajouter (numéros de chaîne)
{
renvoie des nombres.Split(“,”).Select(int.Parse).Sum();
}
Dans la version antérieure à 8.0 de C#, le code ci-dessus est dangereux. La variable nombres pourrait être nulle, ce qui provoquerait une NullReferenceException lors de la tentative d'utilisation de la méthode Split.
Avec la fonctionnalité de types de référence nullables de C # 8.0, vous seriez en sécurité. La variable ne pourrait jamais être nulle et l'appel à la méthode Split ne serait jamais levé. Toute tentative de transmission de null à la méthode Add entraînerait une erreur de compilation.
Mais que se passe-t-il si vous vouliez autoriser les nombres nuls ? Dans ce cas, il vous suffirait d'ajouter un point d'interrogation après le nom du type :
statique int Ajouter(chaîne ? nombres)
{
renvoie des nombres.Split(“,”).Select(int.Parse).Sum();
}
Maintenant, les choses changent radicalement. Puisque les nombres peuvent maintenant être nuls, le compilateur vous incitera à vérifier la valeur de la variable, avec un avertissement (vous pouvez transformer l'avertissement en une erreur du compilateur, pour encore plus de sécurité) :

Le compilateur me fait savoir que les "nombres" peuvent être nuls. Les solutions possibles incluent :
- Utilisation d'une instruction if pour s'assurer que la variable a une référence valide
- Utilisation de l'opérateur null-coalescing déjà mentionné lors de l'appel de la méthode Split
- Rendre à nouveau la variable "numbers" non nulle, en supprimant le point d'interrogation
- Supprimez la règle qui nous donne l'avertissement (ce qui irait à l'encontre de tout l'objectif, mais bon, c'est une option.)
Gardez à l'esprit que cette fonctionnalité est opt-in. Autrement dit, il est désactivé par défaut et vous devez l'activer dans la configuration de votre projet. La raison en est que l'envoi de la fonctionnalité déjà activée entraînerait des modifications avec rupture dans la plupart des bases de code.
Quelles sont les prochaines étapes?
Les exceptions de référence nulle sont un problème très courant dans .NET et dans la plupart des langages de programmation. Heureusement, nous pouvons tous blâmerTony Hoare. Il a inventé des références nulles et l'appelle même l'erreur d'un milliard de dollars.
Blague à part, comment éviter un tel problème ? Une alternative consiste à suivre ma règle d'or :s'il peut être nul, il sera nul !
De nos jours, heureusement, nous pouvons avoir l'aide du compilateur lui-même pour lutter contre l'exception NullReferenceException. Activez la fonctionnalité "types de référence nullables" dans C # 8.0, et de cette façon, vous pourrez empêcher les choses d'être nulles si vous le souhaitez. Cela nous permet de nous amuser sur mon ancienne règle : si elle ne peut pas être nulle, elle ne sera jamais nulle. Le compilateur ne le permettra pas !
Voulez-vous en savoir plus sur C#, les exceptions et d'autres sujets connexes ? Si c'est le cas, restez à l'écoute desStackifier les blogs, puisque nous publions toujours des articles sur ces sujets et plus encore.
Préfixe Stackify : les développeurs de code profiler peuvent faire confiance
Avant de pousser votre code, vous devez améliorer l'expérience utilisateur et optimiser les goulots d'étranglement. Pour rendre cela possible, assurez-vous de tirer parti de la puissance des outils à votre disposition. Prenez les outils Stackify par exemple.Empilerpropose un outil appeléPréfixe, qui vous permet de surveiller votre application Web écrite en .NET, Java, PHP, Node.js, Python ou Ruby.
Prefix est un profileur de code très léger qui peut aider même les développeurs les plus expérimentés à découvrir les requêtes SQL lentes et même les exceptions cachées. Avec Prefix, les développeurs peuvent valider les performances de leur code tel qu'il est écrit. En conséquence, ils poussent un meilleur code pour tester et reçoivent moins de tickets de support.
Stackify récemment introduitPréfixe v4qui est encore actuellement en version bêta. Cette version est une reconstruction améliorée de l'outil de profilage éprouvé de Stackify.
Avec ce nouveau préfixe amélioré, les développeurs bénéficient d'une plus grande prise en charge du système d'exploitation, de plus de langages de programmation, d'un profilage .NET moderne, d'un visualiseur de journaux dédié, et Prefix est désormais une application native pour Windows et macOS.
Non seulement que. Pendant que vous exécutez vos applications, Prefix travaille sa magie en arrière-plan en fournissant des instantanés détaillés de toutes les requêtes Web. Avec Stackify Prefix, vous pourrez suivre les performances de votre application et également trouver des exceptions cachées, des requêtes lentes et d'autres problèmes.Téléchargez le préfixe aujourd'hui.
Améliorez votre code avec Retrace APM
Les outils APM de Stackify sont utilisés par des milliers de développeurs .NET, Java, PHP, Node.js, Python et Ruby dans le monde entier.
Explorez les fonctionnalités du produit Retrace pour en savoir plus.
- Gestion des performances des applications
- Profilage de code
- Suivi des erreurs
- Journalisation centralisée
Apprendre encore plus
Auteur
réveillez-vous
Plus d'articles de mwatson