31 Question: Qu'est-ce qu'une exception NullReferenceException et comment y remédier?

question créée à Sun, Sep 3, 2017 12:00 AM

J'ai du code et quand il s'exécute, il lance un NullReferenceException en disant:

  

La référence à un objet n'est pas définie sur une instance d'objet.

Qu'est-ce que cela signifie et que puis-je faire pour corriger cette erreur?

    
1877
  1. L'assistant d'exception de VS 2017 sera plus utile pour diagnostiquer la cause de cette exception - blogs.msdn.microsoft.com/visualstudio/2016 11/28/… sous Nouvel assistant d'exception .
    2016-12-29 09: 06: 19Z
  2. Chers futurs visiteurs, les réponses à cette question valent également pour une ArgumentNullException . Si votre question a été résolue comme une copie de celle-ci et que vous rencontrez un problème ANE, suivez les instructions fournies dans les réponses pour déboguer et résoudre votre problème.
    2017-10-13 17: 56: 23Z
  3. @ ANE ne devrait se produire que si une valeur null est passée en tant que paramètre. Pouvez-vous donner un exemple si une question de l'ANE était fermée comme une copie de celle-ci?
    2017-10-14 21: 44: 46Z
  4. Il est apparu sur Meta, mais je devais aller chercher le lien. Mais en ce qui concerne ce commentaire, un ANE est simplement un NRE mais quelqu'un a ajouté un contrôle préventif, et vous savez au moins exactement ce qui est null (le nom de l'argument est fourni), il est donc un peu plus facile à diagnostiquer qu'un NRE direct. /div>
    2017-10-16 12: 53: 02Z
    30 réponses                              30                         

    Quelle est la cause?

    Résultat final

    Vous essayez d'utiliser quelque chose qui est null (ou Nothing dans VB.NET). Cela signifie que vous le définissez sur null ou que vous ne le définissez jamais.

    Comme toute autre chose, null est distribué. S'il s'agit de null dans la méthode "A", c'est peut-être que la méthode "B" a transmis une méthode null à à la méthode "A".

    null peut avoir différentes significations:

    1. Les variables d'objet non initialisées et, par conséquent, ne pointent à rien. Dans ce cas, si vous accédez aux propriétés ou aux méthodes de tels objets, un NullReferenceException est généré.
    2. Le développeur utilise null intentionnellement pour indiquer qu'aucune valeur significative n'est disponible. Notez que C # utilise le concept de types de données Nullable pour les variables (comme les tables de base de données peuvent avoir des champs Nullable) - vous pouvez affecter null à eux d’indiquer qu’il n’y a pas de valeur stockée, par exemple int? a = null; où le point d’interrogation indique qu’il est permis de stocker null dans la variable a. Vous pouvez vérifier cela avec if (a.HasValue) {...} ou avec if (a==null) {...}. Les variables nullables, comme a cet exemple, permettent d’accéder à la valeur via a.Value explicitement, ou tout aussi normalement via a.
      Notez que si vous y accédez via a.Value, un InvalidOperationException est renvoyé au lieu d'un NullReferenceException si a correspond à null - vous devez effectuer le contrôle à l'avance, c'est-à-dire que si vous avez une autre variable int b; à valeur Null, vous devez effectuer des affectations. comme if (a.HasValue) { b = a.Value; } ou if (a != null) { b = a; } plus court.

    La suite de cet article va plus en détail et montre les erreurs que beaucoup de programmeurs commettent souvent qui peuvent conduire à un NullReferenceException.

    Plus spécifiquement

    Le moteur d'exécution NullReferenceException toujours signifie la même chose: vous essayez d'utiliser une référence et la référence n'est pas initialisée (ou elle a été une fois initialisée, mais n'est plus initialisé).

    Cela signifie que la référence est null et que vous ne pouvez pas accéder à des membres (tels que des méthodes) via une référence null. Le cas le plus simple:

     
    string foo = null;
    foo.ToUpper();
    

    Ceci jettera un NullReferenceException à la deuxième ligne car vous ne pouvez pas appeler la méthode d'instance ToUpper() sur une référence string pointant vers null.

    Débogage

    Comment trouvez-vous la source d'un NullReferenceException? En plus de regarder l’exception elle-même, qui sera projetée exactement à l’endroit où elle se produit, lePlusieurs méthodes de débogage dans Visual Studio s'appliquent: placez des points d'arrêt stratégiques et inspectez vos variables . , soit en survolant leurs noms, en ouvrant une fenêtre (Quick) Watch ou en utilisant les différents panneaux de débogage, tels que Locals et Autos.

    Si vous souhaitez savoir où la référence est définie ou non, cliquez avec le bouton droit de la souris sur son nom et sélectionnez "Rechercher toutes les références". Vous pouvez ensuite placer un point d'arrêt à chaque emplacement trouvé et exécuter votre programme avec le débogueur attaché. À chaque coupure du débogueur sur un tel point d'arrêt, vous devez déterminer si vous vous attendez à ce que la référence soit non nulle, inspectez la variable et vérifiez qu'elle pointe vers une instance à laquelle vous vous attendez.

    En suivant le flux de programme de cette manière, vous pouvez trouver l'emplacement où l'instance ne doit pas être nulle et la raison pour laquelle elle n'est pas correctement définie.

    Exemples

    Certains scénarios courants dans lesquels l'exception peut être levée:

    Générique

     
    ref1.ref2.ref3.member
    

    Si ref1 ou ref2 ou ref3 est nul, vous obtiendrez un NullReferenceException. Si vous souhaitez résoudre le problème, recherchez celle qui est nulle en récrivant l'expression à son équivalent plus simple:

     
    var r1 = ref1;
    var r2 = r1.ref2;
    var r3 = r2.ref3;
    r3.member
    

    Plus précisément, dans HttpContext.Current.User.Identity.Name, HttpContext.Current peut être null ou la propriété User peut être null, ou la propriété Identity peut être null.

    Indirect

     
    public class Person {
        public int Age { get; set; }
    }
    public class Book {
        public Person Author { get; set; }
    }
    public class Example {
        public void Foo() {
            Book b1 = new Book();
            int authorAge = b1.Author.Age; // You never initialized the Author property.
                                           // there is no Person to get an Age from.
        }
    }
    

    Si vous souhaitez éviter la référence null enfant (Personne), vous pouvez l'initialiser dans le constructeur de l'objet parent (Livre).

    Initialiseurs d'objet imbriqués

    La même chose s'applique aux initialiseurs d'objet imbriqués:

     
    Book b1 = new Book { Author = { Age = 45 } };
    

    Cela se traduit par

     
    Book b1 = new Book();
    b1.Author.Age = 45;
    

    Bien que le mot clé new soit utilisé, il ne crée qu'une nouvelle instance de Book, mais pas une nouvelle instance de Person. La propriété Author est donc toujours null.

    Initialiseurs de collection imbriqués

     
    public class Person {
        public ICollection<Book> Books { get; set; }
    }
    public class Book {
        public string Title { get; set; }
    }
    

    Les initialiseurs de collection imbriqués se comportent de la même manière:

     
    Person p1 = new Person {
        Books = {
            new Book { Title = "Title1" },
            new Book { Title = "Title2" },
        }
    };
    

    Cela se traduit par

     
    Person p1 = new Person();
    p1.Books.Add(new Book { Title = "Title1" });
    p1.Books.Add(new Book { Title = "Title2" });
    

    Le new Person crée uniquement une instance de Person, mais la collection Books est toujours null. La syntaxe d'initialisation de la collection ne crée pas de collection pour p1.Books, cela ne se traduit que par les déclarations p1.Books.Add(...).

    Tableau

     
    int[] numbers = null;
    int n = numbers[0]; // numbers is null. There is no array to index.
    

    Éléments de tableau

     
    Person[] people = new Person[5];
    people[0].Age = 20 // people[0] is null. The array was allocated but not
                       // initialized. There is no Person to set the Age for.
    

    Tableaux dentelés

     
    long[][] array = new long[1][];
    array[0][0] = 3; // is null because only the first dimension is yet initialized.
                     // Use array[0] = new long[2]; first.
    

    Collection /Liste /Dictionnaire

     
    Dictionary<string, int> agesForNames = null;
    int age = agesForNames["Bob"]; // agesForNames is null.
                                   // There is no Dictionary to perform the lookup.
    

    Variable de plage (indirecte /différée)

     
    public class Person {
        public string Name { get; set; }
    }
    var people = new List<Person>();
    people.Add(null);
    var names = from p in people select p.Name;
    string firstName = names.First(); // Exception is thrown here, but actually occurs
                                      // on the line above.  "p" is null because the
                                      // first element we added to the list is null.
    

    Événements

     
    public class Demo
    {
        public event EventHandler StateChanged;
    
        protected virtual void OnStateChanged(EventArgs e)
        {        
            StateChanged(this, e); // Exception is thrown here 
                                   // if no event handlers have been attached
                                   // to StateChanged event
        }
    }
    

    Conventions de dénomination incorrectes:

    Si vous avez nommé les champs différemment des sections locales, vous avez peut-être réalisé que vous n'aviez jamais initialisé le champ.

     
    public class Form1 {
        private Customer customer;
    
        private void Form1_Load(object sender, EventArgs e) {
            Customer customer = new Customer();
            customer.Name = "John";
        }
    
        private void Button_Click(object sender, EventArgs e) {
            MessageBox.Show(customer.Name);
        }
    }
    

    Cela peut être résolu en suivant la convention voulant que les champs soient précédés d'un trait de soulignement:

     
    private Customer _customer;
    

    Cycle de vie d'une page ASP.NET:

     
    public partial class Issues_Edit : System.Web.UI.Page
    {
        protected TestIssue myIssue;
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // Only called on first load, not when button clicked
                myIssue = new TestIssue(); 
            }
        }
    
        protected void SaveButton_Click(object sender, EventArgs e)
        {
            myIssue.Entry = "NullReferenceException here!";
        }
    }
    

    Valeurs de session ASP.NET

     
    // if the "FirstName" session value has not yet been set,
    // then this line will throw a NullReferenceException
    string firstName = Session["FirstName"].ToString();
    

    Modèles de vue vides ASP.NET MVC

    Si l'exception se produit lors du référencement d'une propriété de @Model dans une vue ASP.NET MVC, vous devez comprendre que le Model est défini dans votre méthode d'action, lorsque vous return une vue. Lorsque vous renvoyez un modèle (ou une propriété de modèle) vide à partir de votre contrôleur, l'exception se produit lorsque les vues y accèdent:

     
    // Controller
    public class Restaurant:Controller
    {
        public ActionResult Search()
        {
             return View();  // Forgot the provide a Model here.
        }
    }
    
    // Razor view 
    @foreach (var restaurantSearch in Model.RestaurantSearch)  // Throws.
    {
    }
    
    <p>@Model.somePropertyName</p> <!-- Also throws -->
    

    Ordre et événements de création de contrôle WPF

    Les contrôles WPF sont créés lors de l’appel de InitializeComponent dans l’ordre dans lequel ils apparaissent dans l’arbre visuel. Un NullReferenceException sera généré dans le cas de contrôles créés antérieurement avec des gestionnaires d'événements, etc., activés au cours de InitializeComponent, qui font référence à des contrôles créés tardivement.

    Par exemple:

     
    <Grid>
        <!-- Combobox declared first -->
        <ComboBox Name="comboBox1" 
                  Margin="10"
                  SelectedIndex="0" 
                  SelectionChanged="comboBox1_SelectionChanged">
            <ComboBoxItem Content="Item 1" />
            <ComboBoxItem Content="Item 2" />
            <ComboBoxItem Content="Item 3" />
        </ComboBox>
    
        <!-- Label declared later -->
        <Label Name="label1" 
               Content="Label"
               Margin="10" />
    </Grid>
    

    Ici, comboBox1 est créé avant label1. Si comboBox1_SelectionChanged tente de faire référence à `label1, il n'aura pas encore été créé.

     
    private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        label1.Content = comboBox1.SelectedIndex.ToString(); // NullReference here!!
    }
    

    Changer l’ordre des déclarations dans le code XAML (c’est-à-dire que répertorier label1 avant comboBox1 sans tenir compte des problèmes de conception, résoudrait au moins le NullReferenceException ici.

    Cast avec as

     
    var myThing = someObject as Thing;
    

    Cela ne déclenche pas une exception InvalidCastException mais renvoie un null lorsque la conversion échoue (et lorsque someObject est lui-même null). Soyez donc conscient de cela.

    LINQ FirstOrDefault () et SingleOrDefault ()

    Les versions simples First() et Single() lèvent des exceptions s’il n’ya rien. Les versions "OrDefault" renvoient null dans ce cas. Soyez donc conscient de cela.

    foreach

    foreach renvoie lorsque vous essayez de parcourir la collection null. Cela est généralement dû à des résultats inattendus provenant null de méthodes renvoyant des collections.

     
     List<int> list = null;    
     foreach(var v in list) { } // exception
    

    Exemple plus réaliste - sélectionnez des nœuds dans un document XML. Lance si les noeuds ne sont pas trouvés mais que le débogage initial montre que toutes les propriétés sont valides:

     
     foreach (var node in myData.MyXml.DocumentNode.SelectNodes("//Data"))
    

    Moyens d'éviter

    Recherchez explicitement null et ignore les valeurs nulles.

    Si vous vous attendez à ce que la référence soit parfois nulle, vous pouvez vérifier qu'elle est null avant d'accéder aux membres de l'instance:

     
    void PrintName(Person p) {
        if (p != null) {
            Console.WriteLine(p.Name);
        }
    }
    

    Recherchez explicitement null et fournissez une valeur par défaut.

    L'appel aux méthodes que vous comptez renvoyer à une instance peut renvoyer null, par exemple lorsque l'object être recherché ne peut pas être trouvé. Vous pouvez choisir de renvoyer une valeur par défaut lorsque c'est le cas:

     
    string GetCategory(Book b) {
        if (b == null)
            return "Unknown";
        return b.Category;
    }
    

    Recherchez explicitement null dans les appels de méthodes et générez une exception personnalisée.

    Vous pouvez également lever une exception personnalisée, uniquement pour l'attraper dans le code d'appel:

     
    string GetCategory(string bookTitle) {
        var book = library.FindBook(bookTitle);  // This may return null
        if (book == null)
            throw new BookNotFoundException(bookTitle);  // Your custom exception
        return book.Category;
    }
    

    Utilisez Debug.Assert si une valeur ne doit jamais être null, afin d’attraper le problème plus tôt que l’exception ne se produit.

    Lorsque vous savez, au cours du développement, qu’une méthode peut peut-être, mais ne doit jamais renvoyer null, vous pouvez utiliser Debug.Assert() pour interrompre le processus dès que possible:

     
    string GetTitle(int knownBookID) {
        // You know this should never return null.
        var book = library.GetBook(knownBookID);  
    
        // Exception will occur on the next line instead of at the end of this method.
        Debug.Assert(book != null, "Library didn't return a book for known book ID.");
    
        // Some other code
    
        return book.Title; // Will never throw NullReferenceException in Debug mode.
    }
    

    Bien que cette vérification ne se retrouve pas dans votre version de version , ce qui entraîne de lancer à nouveau le NullReferenceException lorsque book == null au moment de l'exécution en mode de lancement.

    Utilisez GetValueOrDefault() pour les types de valeur Nullable pour fournir une valeur par défaut quand ils sont null.

     
    DateTime? appointment = null;
    Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));
    // Will display the default value provided (DateTime.Now), because appointment is null.
    
    appointment = new DateTime(2022, 10, 20);
    Console.WriteLine(appointment.GetValueOrDefault(DateTime.Now));
    // Will display the appointment date, not the default
    

    Utilisez l'opérateur de fusion nul: ?? [C #] ou If() [VB].

    Le raccourci pour fournir une valeur par défaut lorsqu'un null est rencontré:

     
    IService CreateService(ILogger log, Int32? frobPowerLevel)
    {
        var serviceImpl = new MyService(log ?? NullLog.Instance);
    
        // Note that the above "GetValueOrDefault()" can also be rewritten to use
        // the coalesce operator:
        serviceImpl.FrobPowerLevel = frobPowerLevel ?? 5;
    }
    

    Utilisez l'opérateur de condition null: ?. ou ?[x] pour les tableaux (disponible en C # 6 et VB.NET 14):

    Ceci est aussi parfois appelé l'opérateur de navigation sécurisée ou Elvis (après sa forme). Si l'expression sur le côté gauche de l'opérateur est null, le côté droit ne sera pas évalué et null sera renvoyé. Cela signifie des cas comme celui-ci:

     
    var title = person.Title.ToUpper();
    

    Si la personne n'a pas de titre, une exception sera lancée car elle tente d'appeler ToUpper sur une propriété avec une valeur null.

    En C # 5 et inférieur, cela peut être protégé avec:

     
    var title = person.Title == null ? null : person.Title.ToUpper();
    

    Maintenant, la variable de titre sera null au lieu de lancer une exception. C # 6 introduit une syntaxe plus courte pour ceci:

     
    var title = person.Title?.ToUpper();
    

    La variable de titre sera donc null et l'appel à ToUpper ne sera pas effectué si person.Title est null.

    Bien sûr, vous devez toujours vérifier title pour null ou utiliser l'opérateur de condition NULL avec l'opérateur de coalescence NULL (??) pour fournir une valeur par défaut:

     
    // regular null check
    int titleLength = 0;
    if (title != null)
        titleLength = title.Length; // If title is null, this would throw NullReferenceException
    
    // combining the `?` and the `??` operator
    int titleLength = title?.Length ?? 0;
    

    De même, pour les tableaux, vous pouvez utiliser ?[i] comme suit:

     
    int[] myIntArray=null;
    var i=5;
    int? elem = myIntArray?[i];
    if (!elem.HasValue) Console.WriteLine("No value");
    

    Ceci fera ce qui suit: Si myIntArray est null, l'expression retourne null et vous pouvez le vérifier en toute sécurité. S'il contient un tableau, il fera la même chose que:  elem = myIntArray[i]; et renvoie l'élément i th .

    Techniques spéciales pour le débogage et la résolution des derefs null dans les itérateurs

    C # prend en charge les "blocs itérateurs" (appelés "générateurs" dans d'autres langages populaires). Les exceptions de déréférence Null peuvent être particulièrement difficiles à déboguer dans les blocs d'itérateurs en raison d'une exécution différée:

     
    public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
    {
        for (int i = 0; i < count; ++i)
          yield return f.MakeFrob();
    }
    ...
    FrobFactory factory = whatever;
    IEnumerable<Frobs> frobs = GetFrobs();
    ...
    foreach(Frob frob in frobs) { ... }
    

    Si whatever donne null, alors MakeFrob sera lancé. Vous pensez peut-être que la bonne chose à faire est la suivante:

     
    // DON'T DO THIS
    public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
    {
        if (f == null) 
          throw new ArgumentNullException("f", "factory must not be null");
        for (int i = 0; i < count; ++i)
          yield return f.MakeFrob();
    }
    

    Pourquoi est-ce faux? Parce que le bloc itérateur ne exécute pas avant le foreach! L'appel à GetFrobs renvoie simplement un objet qui lorsqu'il sera itéré exécutera le bloc itérateur.

    En écrivant une vérification NULL comme celle-ci, vous empêchez la déréférence Null, mais vous déplacez l'exception d'argument NULL au point de l'itération , pas au point de l'appel , et cela est très déroutant à déboguer .

    Le correctif correct est:

     
    // DO THIS
    public IEnumerable<Frob> GetFrobs(FrobFactory f, int count)
    {
        // No yields in a public method that throws!
        if (f == null) 
          throw new ArgumentNullException("f", "factory must not be null");
        return GetFrobsForReal(f, count);
    }
    private IEnumerable<Frob> GetFrobsForReal(FrobFactory f, int count)
    {
        // Yields in a private method
        Debug.Assert(f != null);
        for (int i = 0; i < count; ++i)
          yield return f.MakeFrob();
    }
    

    En d’autres termes, créez une méthode d’aide privée dotée de la logique de bloc de l’itérateur et une méthode de surface publique effectuant la vérification nulle et renvoyant l’itérateur. Maintenant, lorsque GetFrobs est appelé, la vérification de la valeur NULL est effectuée immédiatement, puis GetFrobsForReal est exécutée lorsque la séquence est itérée.

    Si vous examinez la source de référence de LINQ to Objects, vous verrez que cette technique est utilisée dans l'ensemble. L'écriture est un peu plus lourde, mais cela facilite beaucoup le débogage des erreurs de nullité. Optimisez votre code pour le confort de l'appelant et non pour l'auteur .

    Une note sur les déréférences nulles dans un code non sécurisé

    C # a un mode "non sécurisé" qui, comme son nom l’indique, est extrêmement dangereux car les mécanismes de sécurité normaux assurant la sécurité de la mémoire et la sécurité du type ne sont pas appliqués. Vous ne devez pas écrire de code non sécurisé à moins de bien comprendre le fonctionnement de la mémoire .

    En mode non sécurisé, vous devez être conscient de deux faits importants:

    • déréférencer un pointeur nul entraîne la même exception que le déréférencement d'une référence
    • la déréférence d'un pointeur non nul non valide peut générer cette exception dans certaines circonstances

    Pour comprendre pourquoi, il est utile de comprendre comment .NET produit d’abord des exceptions de déréférencement nul. (Ces détails s'appliquent à .NET sous Windows; d'autres systèmes d'exploitation utilisent des mécanismes similaires.)

    La mémoire est virtualisée sous Windows. chaque processus obtient un espace mémoire virtuel de plusieursges "de la mémoire suivie par le système d’exploitation. Chaque page de la mémoire possède des indicateurs qui déterminent son utilisation: lecture, écriture, exécution, etc. Le plus bas la page est marquée comme "produire une erreur si elle est utilisée de quelque manière que ce soit".

    Un pointeur nul et une référence nulle en C # sont représentés en interne par le chiffre zéro. Toute tentative de le déréférencer dans la mémoire correspondante provoque alors une erreur du système d'exploitation. Le runtime .NET détecte ensuite cette erreur et la transforme en exception de déréférencement nul.

    C'est pourquoi la déréférence d'un pointeur null et d'une référence null produit la même exception.

    Qu'en est-il du deuxième point? Le déréférencement de tout pointeur non valide qui tombe dans la page la plus basse de la mémoire virtuelle provoque la même erreur de système d'exploitation et, par conséquent, la même exception.

    Pourquoi cela a-t-il un sens? Eh bien, supposons que nous ayons une structure contenant deux ints et un pointeur non géré égal à null. Si nous essayons de déréférencer le second int de la structure, le CLR ne tentera pas d'accéder au stockage à l'emplacement zéro; il accédera au stockage à l'emplacement quatre. Mais logiquement, il s’agit d’un déréférencement nul car nous arrivons à cette adresse via le null.

    Si vous travaillez avec du code non sécurisé et que vous obtenez une exception de déréférencement Null, sachez simplement que le pointeur incriminé n'a pas besoin d'être null. Il peut s’agir de n’importe quel emplacement de la page la plus basse et cette exception sera générée.

        
    2282
    2018-07-18 06: 27: 33Z
    1. Peut-être qu'il s'agit d'un commentaire idiot, mais que le premier et le meilleur moyen d'éviter ce problème consiste à initialiser l'objet? Pour moi, si cette erreur se produit, c'est généralement parce que j'ai oublié d'initialiser quelque chose comme l'élément array. Je pense qu'il est beaucoup moins courant de définir l'objet comme nul et de le référencer ensuite. Peut-être donner le moyen de résoudre chaque problème adjacent à la description. Encore un bon post.
      2014-05-20 06: 39: 13Z
    2. Que faire s'il n'y a pas d'objet, mais plutôt la valeur de retour d'une méthode ou d'une propriété?
      2014-05-20 06: 41: 02Z
    3. L'exemple livre /auteur est un peu bizarre ... Comment se compile-t-il? Comment IntelliSense fonctionne-t-il? Qu'est-ce que je ne suis pas bon avec Computar ...
      2014-09-08 18: 26: 23Z
    4. @ Will: ma dernière modification est-elle utile? Sinon, soyez plus explicite sur ce que vous considérez comme un problème.
      2014-09-08 18: 41: 50Z
    5. @ JohnSaunders Oh, non, désolé, je voulais dire la version de l'initialiseur d'objet de cela. new Book { Author = { Age = 45 } }; Comment l’initialisation interne même ... Je ne peux pas penser à une situation dans laquelle un init interne fonctionnerait, alors qu’il compile et que intellisense fonctionne ... Sauf pour les structures?
      2014-09-08 18: 44: 35Z

    Exception NullReference - Visual Basic

    Le code NullReference Exception pour Visual Basic n'est pas différent de celui de C # . Après tout, ils signalent tous les deux la même exception définie dans le .NET Framework qu'ils utilisent tous les deux. Les causes propres à Visual Basic sont rares (peut-être une seule).

    Cette réponse utilisera les termes, la syntaxe et le contexte Visual Basic. Les exemples utilisés proviennent d'un grand nombre de questions précédentes relatives au débordement de pile. Cela permet de maximiser la pertinence en utilisant les types de situations souvent observées dans les publications. Un peu plus d'explications est également fourni pour ceux qui pourraient en avoir besoin. Un exemple similaire au vôtre est très probablement répertorié ici.

    Remarque:

    1. Ceci est basé sur un concept: il n'y a pas de code à coller dans votre projet. Il a pour but de vous aider à comprendre les causes d’un NullReferenceException (NRE), à le localiser, à le réparer et à l’éviter. Une NRE peut être provoquée de plusieurs façons, il est donc peu probable que ce soit votre seule rencontre.
    2. Les exemples (extraits de Stack Overflow) ne montrent pas toujours le meilleur moyen de faire quelque chose en premier lieu.
    3. Généralement, le remède le plus simple est utilisé.

    BasicSignification

    Le message "L'objet n'est pas défini sur une instance d'Object" signifie que vous essayez d'utiliser un objet qui n'a pas été initialisé. Cela se résume à l’un de ces éléments:

    • Votre code a déclaré une variable d'objet, mais il ne l'a pas initialisé (créer une instance ou l '' instancier ')
    • Quelque chose qui, selon votre code, initialise un objet, n'a pas été
    • Éventuellement, un autre code a invalidé prématurément un objet encore utilisé

    Recherche de la cause

    Comme le problème est une référence d'objet Nothing, la solution consiste à les examiner pour déterminer laquelle. Puis déterminez pourquoi il n'est pas initialisé. Maintenez la souris sur les différentes variables et Visual Studio (VS) affichera leurs valeurs - le coupable sera Nothing.

    Affichage du débogage de l'EDI

    Vous devez également supprimer tous les blocs Try /Catch du code approprié, en particulier ceux pour lesquels il n'y a rien dans le bloc Catch. Cela provoquera le blocage de votre code lorsqu'il essaiera d'utiliser un objet qui est Nothing. C’est ce que vous souhaitez , car il identifiera l'emplacement exact du problème et vous permettra d'identifier l'objet qui l'a provoqué.

    Un MsgBox dans la capture qui affiche Error while... sera de peu d'aide. Cette méthode conduit également à des très mauvaises questions sur le dépassement de pile, car vous ne pouvez pas décrire l’exception réelle, l’objet impliqué ou même la ligne de code où elle se produit.

    Vous pouvez également utiliser le Locals Window ( Débogage - > Windows - &Locaux ) pour examiner vos objets.

    Une fois que vous connaissez le problème et son emplacement, il est généralement assez facile à résoudre et plus rapide que de poser une nouvelle question.

    Voir aussi:

    Exemples et solutions

    Objets de classe /Création d'une instance

     
    Dim reg As CashRegister
    ...
    TextBox1.Text = reg.Amount         ' NRE
    

    Le problème est que Dim ne crée pas d’objet CashRegister ; il ne déclare qu'une variable nommée reg de ce type. Déclarer une variable d'objet et créer une instance sont deux choses différentes.

    Remède

    L'opérateur New peut souvent être utilisé pour créer l'instance lorsque vous la déclarez:

     
    Dim reg As New CashRegister        ' [New] creates instance, invokes the constructor
    
    ' Longer, more explicit form:
    Dim reg As CashRegister = New CashRegister
    

    Lorsqu'il est seulement approprié de créer l'instance ultérieurement:

     
    Private reg As CashRegister         ' Declare
      ...
    reg = New CashRegister()            ' Create instance
    

    Remarque: ne pas réutiliser Dim dans une procédure, y compris le constructeur (Sub New):

     
    Private reg As CashRegister
    '...
    
    Public Sub New()
       '...
       Dim reg As New CashRegister
    End Sub
    

    Ceci créera une variable locale , reg, qui n'existe que dans ce contexte (sub). La variable reg avec le niveau de module Scope que vous utiliserez partout reste Nothing.

      

    L'opérateur New manquant est la cause n ° 1 de NullReference Exceptions observée dans les questions sur le dépassement de capacité analysées.

         

    Visual Basic tente de clarifier le processus à plusieurs reprises à l'aide de New : l'utilisation de l'opérateur New crée un objet nouveau et appelle Sub New - le constructeur: votre objet peut effectuer toute autre initialisation.

    Pour être clair, Dim (ou Private) uniquement déclare une variable et son Type. Le Scope de la variable - qu'il existe pour l'ensemble du module /de la classe ou s'il est local à une procédure - est déterminé par il est déclaré. Private | Friend | Public définit le niveau d'accès, pas Scope .

    Pour plus d'informations, voir:

    Tableaux

    Les tableaux doivent également être instanciés:

     
    Private arr as String()
    

    Ce tableau a seulement été déclaré, pas créé. Il existe plusieurs façons d’initialiser un tableau:

     
    Private arr as String() = New String(10){}
    ' or
    Private arr() As String = New String(10){}
    
    ' For a local array (in a procedure) and using 'Option Infer':
    Dim arr = New String(10) {}
    

    Remarque: à partir de VS 2010, lors de l'initialisation d'un tableau local à l'aide d'un littéral et de Option Infer, les éléments As <Type> et New sont facultatifs:

     
    Dim myDbl As Double() = {1.5, 2, 9.9, 18, 3.14}
    Dim myDbl = New Double() {1.5, 2, 9.9, 18, 3.14}
    Dim myDbl() = {1.5, 2, 9.9, 18, 3.14}
    

    Le type de données et la taille du tableau sont déduits des données assignées. Les déclarations de niveau classe /module nécessitent toujours As <Type> avec Option Strict:

     
    Private myDoubles As Double() = {1.5, 2, 9.9, 18, 3.14}
    

    Exemple: tableau d'objets de classe

     
    Dim arrFoo(5) As Foo
    
    For i As Integer = 0 To arrFoo.Count - 1
       arrFoo(i).Bar = i * 10       ' Exception
    Next
    

    Le tableau a été créé, mais pas les Foo objets qu'il contient.

    Remède

     
    For i As Integer = 0 To arrFoo.Count - 1
        arrFoo(i) = New Foo()         ' Create Foo instance
        arrFoo(i).Bar = i * 10
    Next
    

    L'utilisation d'un List(Of T) rendra assez difficile la création d'un élément sans objet valide:

     
    Dim FooList As New List(Of Foo)     ' List created, but it is empty
    Dim f As Foo                        ' Temporary variable for the loop
    
    For i As Integer = 0 To 5
        f = New Foo()                    ' Foo instance created
        f.Bar =  i * 10
        FooList.Add(f)                   ' Foo object added to list
    Next
    

    Pour plus d'informations, voir:

    Listes et collections

    Les collections .NET (parmi lesquelles il existe de nombreuses variétés - listes, dictionnaire, etc.) doivent également être instanciées ou créées.

     
    Private myList As List(Of String)
    ..
    myList.Add("ziggy")           ' NullReference
    

    Vous obtenez la même exception pour la même raison: myList a été uniquement déclaré, mais aucune instance n'a été créée. Le remède est le même:

     
    myList = New List(Of String)
    
    ' Or create an instance when declared:
    Private myList As New List(Of String)
    

    Un oubli commun est une classe qui utilise une collection Type:

     
    Public Class Foo
        Private barList As List(Of Bar)
    
        Friend Function BarCount As Integer
            Return barList.Count
        End Function
    
        Friend Sub AddItem(newBar As Bar)
            If barList.Contains(newBar) = False Then
                barList.Add(newBar)
            End If
        End Function
    

    L'une ou l'autre procédure aboutira à un NRE, car barList est seulement déclaré, pas instancié. La création d'une instance de Foo ne créera pas également une instance de l'interne barList. L’intention de le faire peut-être dans le constructeur:

     
    Public Sub New         ' Constructor
        ' Stuff to do when a new Foo is created...
        barList = New List(Of Bar)
    End Sub
    

    Comme auparavant, cela est incorrect:

     
    Public Sub New()
        ' Creates another barList local to this procedure
         Dim barList As New List(Of Bar)
    End Sub
    

    Pour plus d'informations, voir List(Of T) Class .

    Objets du fournisseur de données

    L'utilisation de bases de données offre de nombreuses possibilités pour une référence null car il peut y avoir de nombreux objets (Command, Connection, Transaction, Dataset, DataTable, DataRows, ...) simultanément utilisés. Remarque: Le fournisseur de données que vous utilisez (MySQL, SQL Server, OleDB, etc.) n'a pas d'importance. Les concepts sont identiques.

    Exemple 1

     
    Dim da As OleDbDataAdapter
    Dim ds As DataSet
    Dim MaxRows As Integer
    
    con.Open()
    Dim sql = "SELECT * FROM tblfoobar_List"
    da = New OleDbDataAdapter(sql, con)
    da.Fill(ds, "foobar")
    con.Close()
    
    MaxRows = ds.Tables("foobar").Rows.Count      ' Error
    

    Comme auparavant, l'objet ds Dataset a été déclaré, mais aucune instance n'a jamais été créée. Le DataAdapter remplira un DataSet existant, pas en créer un. Dans ce cas, étant donné que ds est une variable locale, l'EDI vous avertit que cela pourrait se produire:

    img

    Lorsqu'il est déclaré en tant que variable de niveau module /classe, comme cela semble être le cas avec con, le compilateur ne peut pas savoir si l'objet a été créé par une procédure en amont. Ne pas ignorer les avertissements.

    Remède

     
    Dim ds As New DataSet
    

    Exemple 2

     
    ds = New DataSet
    da = New OleDBDataAdapter(sql, con)
    da.Fill(ds, "Employees")
    
    txtID.Text = ds.Tables("Employee").Rows(0).Item(1)
    txtID.Name = ds.Tables("Employee").Rows(0).Item(2)
    

    Une faute de frappe est un problème ici: Employees vs Employee. Il n'y a pas eu de DataTable nommé "Employé" créé, donc un NullReferenceException résultats tente d'y accéder. Un autre problème potentiel est de supposer qu'il y aura Items qui ne le sera peut-être pas lorsque le code SQL inclut une clause WHERE.

    Remède

    Comme cela utilise une table, l’utilisation de Tables(0) évitera les erreurs d’orthographe. L'examen Rows.Count peut également aider:

     
    If ds.Tables(0).Rows.Count > 0 Then
        txtID.Text = ds.Tables(0).Rows(0).Item(1)
        txtID.Name = ds.Tables(0).Rows(0).Item(2)
    End If
    

    Fill est une fonction renvoyant le nombre de Rows affectés qui peut également être testée:

     
    If da.Fill(ds, "Employees") > 0 Then...
    

    Exemple 3

     
    Dim da As New OleDb.OleDbDataAdapter("SELECT TICKET.TICKET_NO,
            TICKET.CUSTOMER_ID, ... FROM TICKET_RESERVATION AS TICKET INNER JOIN
            FLIGHT_DETAILS AS FLIGHT ... WHERE [TICKET.TICKET_NO]= ...", con)
    Dim ds As New DataSet
    da.Fill(ds)
    
    If ds.Tables("TICKET_RESERVATION").Rows.Count > 0 Then
    

    Le DataAdapter fournira TableNames comme indiqué dans l'exemple précédent, mais il n'analyse pas les noms de la table SQL ou de la base de données. Par conséquent, ds.Tables("TICKET_RESERVATION") fait référence à une table inexistante.

    La solution est la même, référencez la table par index:

     
    If ds.Tables(0).Rows.Count > 0 Then
    

    Voir aussi Classe DataTable .

    Chemins d'objet /imbriqués

     
    If myFoo.Bar.Items IsNot Nothing Then
       ...
    

    Le code teste uniquement Items, tandis que myFoo et Bar peuvent également être Nothing. Le remède consiste à tester l’ensemble de la chaîne ou du chemin des objets:

     
    If (myFoo IsNot Nothing) AndAlso
        (myFoo.Bar IsNot Nothing) AndAlso
        (myFoo.Bar.Items IsNot Nothing) Then
        ....
    

    AndAlso est important. Les tests suivants ne seront pas effectués une fois la première condition False rencontrée. Cela permet au code de "percer" en toute sécurité dans le ou les objets, un "niveau" à la fois, en évaluant myFoo.Bar uniquement après (et si) myFoo est considéré comme valide. Les chaînes ou chemins d’objets peuvent être assez longs lors du codage d’objets complexes:

     
    myBase.myNodes(3).Layer.SubLayer.Foo.Files.Add("somefilename")
    

    Il n'est pas possible de référencer quoi que ce soit en "aval" d'un objet null. Ceci s'applique également aux contrôles:

     
    myWebBrowser.Document.GetElementById("formfld1").InnerText = "some value"
    

    Ici, myWebBrowser ou Document peuvent être nuls ou l'élément formfld1 peut ne pas exister.

    Contrôles de l'interface utilisateur

     
    Dim cmd5 As New SqlCommand("select Cartons, Pieces, Foobar " _
         & "FROM Invoice where invoice_no = '" & _
         Me.ComboBox5.SelectedItem.ToString.Trim & "' And category = '" & _
         Me.ListBox1.SelectedItem.ToString.Trim & "' And item_name = '" & _
         Me.ComboBox2.SelectedValue.ToString.Trim & "' And expiry_date = '" & _
         Me.expiry.Text & "'", con)
    

    Entre autres choses, ce code ne prévoit pas que l'utilisateur peut ne pas avoir sélectionné quelque chose dans un ou plusieurs contrôles de l'interface utilisateur. ListBox1.SelectedItem pourrait bien être Nothing, donc ListBox1.SelectedItem.ToString entraînera un NRE.

    Remède

    Validez les données avant de les utiliser (utilisez également les paramètres Option Strict et SQL):

     
    Dim expiry As DateTime         ' for text date validation
    If (ComboBox5.SelectedItems.Count > 0) AndAlso
        (ListBox1.SelectedItems.Count > 0) AndAlso
        (ComboBox2.SelectedItems.Count > 0) AndAlso
        (DateTime.TryParse(expiry.Text, expiry) Then
    
        '... do stuff
    Else
        MessageBox.Show(...error message...)
    End If
    

    Vous pouvez également utiliser (ComboBox5.SelectedItem IsNot Nothing) AndAlso...

    .

    Formulaires Visual Basic

     
    Public Class Form1
    
        Private NameBoxes = New TextBox(5) {Controls("TextBox1"), _
                       Controls("TextBox2"), Controls("TextBox3"), _
                       Controls("TextBox4"), Controls("TextBox5"), _
                       Controls("TextBox6")}
    
        ' same thing in a different format:
        Private boxList As New List(Of TextBox) From {TextBox1, TextBox2, TextBox3 ...}
    
        ' Immediate NRE:
        Private somevar As String = Me.Controls("TextBox1").Text
    

    C’est un moyen assez courant d’obtenir un NRE. En C #, selon son codage, l'EDI signalera que Controls n'existe pas dans le contexte actuel ou "ne peut pas faire référence à un membre non statique". Donc, dans une certaine mesure, cette situation est réservée à VB. Il est également complexe car il peut entraîner une défaillance en cascade.

    Les tableaux et les collections ne peuvent pas être initialisés de cette façon. Ce code d'initialisation sera exécuté avant que le constructeur crée le Form ou le Controls. En conséquence:

    • Les listes et la collection seront simplement vides
    • Le tableau contiendra cinq éléments de Nothing
    • L'affectation somevar donnera lieu à une NRE immédiate car rien ne possède une propriété .Text

    Référencer des éléments de tableau ultérieurement entraînera un NRE. Si vous faites cela dans Form_Load, en raison d’un bogue étrange, l’EDI ne peut pas signaler l’exception quand cela se produit. L'exception apparaîtra plus tard lorsque votre code tentera d'utiliser le tableau. Cette "exception silencieuse" est détaillée dans cet article . Pour nous, la clé est que lorsque quelque chose de catastrophique se produit lors de la création d'un formulaire (événement Sub New ou Form Load), les exceptions peuvent ne pas être signalées, le code quitte la procédure et affiche simplement le formulaire.

    Puisqu'aucun autre code de votre événement Sub New ou Form Load ne s'exécutera après le NRE, beaucoup d'autres choses peuvent être laissées non initialisées.

     
    Sub Form_Load(..._
       '...
       Dim name As String = NameBoxes(2).Text        ' NRE
       ' ...
       ' More code (which will likely not be executed)
       ' ...
    End Sub
    

    Remarque : cela s'applique à toutes les références de contrôle et de composant, ce qui les rend illégales lorsqu'elles se trouvent:

     
    Public Class Form1
    
        Private myFiles() As String = Me.OpenFileDialog1.FileName & ...
        Private dbcon As String = OpenFileDialog1.FileName & ";Jet Oledb..."
        Private studentName As String = TextBox13.Text
    

    Remède partiel

    Il est curieux que VB ne fournisse pas d'avertissement, mais la solution consiste à déclarer les conteneurs au niveau du formulaire, mais à les initialiser dans le gestionnaire d'événements de chargement de formulaire lorsque les contrôles existent . Cela peut être fait dans Sub New tant que votre code est après l'appel InitializeComponent:

     
    ' Module level declaration
    Private NameBoxes as TextBox()
    Private studentName As String
    
    ' Form Load, Form Shown or Sub New:
    '
    ' Using the OP's approach (illegal using OPTION STRICT)
    NameBoxes = New TextBox() {Me.Controls("TextBox1"), Me.Controls("TestBox2"), ...)
    studentName = TextBox32.Text           ' For simple control references
    

    Le code du tableau n'est peut-être pas encore sorti du bois. Aucun contrôle qui se trouve dans un contrôle conteneur (comme un GroupBox ou Panel) ne sera trouvé dans Me.Controls; ils figureront dans la collection Controls de ce Panel ou de cette GroupBox. Un contrôle ne sera pas non plus retourné si le nom du contrôle est mal orthographié ("TeStBox2"). Dans ce cas, Nothing sera à nouveau stocké dans ces éléments de tableau et un résultat NRE sera généré lorsque vous tenterez de le référencer.

    Celles-ci devraient être faciles à trouver maintenant que vous savez ce que vous recherchez: VS vous montre l'erreur de votre sens

    "Button2" réside sur un Panel

    Remède

    Plutôt que des références indirectes par nom utilisant la collection Controls du formulaire, utilisez la référence de contrôle:

     
    ' Declaration
    Private NameBoxes As TextBox()
    
    ' Initialization -  simple and easy to read, hard to botch:
    NameBoxes = New TextBox() {TextBox1, TextBox2, ...)
    
    ' Initialize a List
    NamesList = New List(Of TextBox)({TextBox1, TextBox2, TextBox3...})
    ' or
    NamesList = New List(Of TextBox)
    NamesList.AddRange({TextBox1, TextBox2, TextBox3...})
    

    Fonction ne renvoyant rien

     
    Private bars As New List(Of Bars)        ' Declared and created
    
    Public Function BarList() As List(Of Bars)
        bars.Clear
        If someCondition Then
            For n As Integer = 0 to someValue
                bars.Add(GetBar(n))
            Next n
        Else
            Exit Function
        End If
    
        Return bars
    End Function
    

    Il s'agit d'un cas où l'EDI vous avertira que ' tous les chemins ne renvoient pas de valeur et qu'un NullReferenceException peut en résulter '. Vous pouvez supprimer l'avertissement en remplaçant Exit Function par Return Nothing, mais cela ne résout pas le problème. Tout ce qui essaie d'utiliser le retour quand someCondition = False donnera un NRE:

     
    bList = myFoo.BarList()
    For Each b As Bar in bList      ' EXCEPTION
          ...
    

    Remède

    Remplacez Exit Function dans la fonction par Return bList. Le renvoi d'un vide List n'est pas la même chose que le renvoi d'un Nothing. S'il y a une chance qu'un objet retourné puisse être Nothing, testez-le avant de l'utiliser:

     
     bList = myFoo.BarList()
     If bList IsNot Nothing Then...
    

    Essai /capture mal implémenté

    Un Try /Catch mal implémenté peut cacher le problème et en créer de nouveaux:

     
    Dim dr As SqlDataReader
    Try
        Dim lnk As LinkButton = TryCast(sender, LinkButton)
        Dim gr As GridViewRow = DirectCast(lnk.NamingContainer, GridViewRow)
        Dim eid As String = GridView1.DataKeys(gr.RowIndex).Value.ToString()
        ViewState("username") = eid
        sqlQry = "select FirstName, Surname, DepartmentName, ExtensionName, jobTitle,
                 Pager, mailaddress, from employees1 where username='" & eid & "'"
        If connection.State <> ConnectionState.Open Then
            connection.Open()
        End If
        command = New SqlCommand(sqlQry, connection)
    
        'More code fooing and barring
    
        dr = command.ExecuteReader()
        If dr.Read() Then
            lblFirstName.Text = Convert.ToString(dr("FirstName"))
            ...
        End If
        mpe.Show()
    Catch
    
    Finally
        command.Dispose()
        dr.Close()             ' <-- NRE
        connection.Close()
    End Try
    

    C’est le cas où un objet n’est pas créé comme prévu, mais démontre également l’utilité du compteur d’un Catch vide.

    Il existe une virgule supplémentaire dans le code SQL (après "mailaddress") qui entraîne une exception à .ExecuteReader. Après que le Catch n'ait rien fait, Finally tente d'effectuer un nettoyage, mais comme vous ne pouvez Close pas d'objet null DataReader, vous obtenez un tout nouveau résultat NullReferenceException.

    Un bloc Catch vide est le terrain de jeu du diable. Cet OP était déconcerté par le fait qu’il obtenait un NRE dans le bloc Finally. Dans d'autres situations, un Catch vide peut faire en sorte que quelque chose de beaucoup plus loin en aval se détraque et vous oblige à passer du temps à chercher les mauvaises choses au mauvais endroit pour résoudre le problème. (L’exception silencieuse décrite ci-dessus fournit la même valeur de divertissement.)

    Remède

    N'utilisez pas de blocs Try /Catch vides - laissez le code planter afin de pouvoir a) identifier la cause b) identifier l'emplacement et c) appliquer une solution appropriée. Les blocs Try /Catch ne sont pas destinés à masquer les exceptions à la personne spécialement qualifiée pour les résoudre - le développeur.

    DBNull n'est pas la même chose que rien

     
    For Each row As DataGridViewRow In dgvPlanning.Rows
        If Not IsDBNull(row.Cells(0).Value) Then
            ...
    

    La fonction IsDBNull est utilisée pour tester si une valeur égal à System.DBNull: depuis MSDN:

      

    La valeur System.DBNull indique que l’objet représente des données manquantes ou inexistantes. DBNull n'est pas la même chose que Nothing, ce qui indique qu'une variable n'a pas encore été initialisée.

    Remède

     
    If row.Cells(0) IsNot Nothing Then ...
    

    Comme auparavant, vous pouvez tester rien, puis une valeur spécifique:

     
    If (row.Cells(0) IsNot Nothing) AndAlso (IsDBNull(row.Cells(0).Value) = False) Then
    

    Exemple 2

     
    Dim getFoo = (From f In dbContext.FooBars
                   Where f.something = something
                   Select f).FirstOrDefault
    
    If Not IsDBNull(getFoo) Then
        If IsDBNull(getFoo.user_id) Then
            txtFirst.Text = getFoo.first_name
        Else
           ...
    

    FirstOrDefault renvoie le premier élément ou la valeur par défaut, qui est Nothing pour les types de référence et jamais DBNull:

     
    If getFoo IsNot Nothing Then...
    

    Contrôles

     
    Dim chk As CheckBox
    
    chk = CType(Me.Controls(chkName), CheckBox)
    If chk.Checked Then
        Return chk
    End If
    

    Si un CheckBox avec chkName est introuvable (ou existe dans un GroupBox), alors chk sera défini sur Nothing et toute tentative de référence à une propriété entraînera une exception.

    Remède

     
    If (chk IsNot Nothing) AndAlso (chk.Checked) Then ...
    

    Le DataGridView

    La DGV a quelques bizarreries vues périodiquement:

     
    dgvBooks.DataSource = loan.Books
    dgvBooks.Columns("ISBN").Visible = True       ' NullReferenceException
    dgvBooks.Columns("Title").DefaultCellStyle.Format = "C"
    dgvBooks.Columns("Author").DefaultCellStyle.Format = "C"
    dgvBooks.Columns("Price").DefaultCellStyle.Format = "C"
    

    Si dgvBooks a AutoGenerateColumns = True, il créera les colonnes, mais il ne les nomme pas. Par conséquent, le code ci-dessus échoue lorsqu'il les référence par leur nom.

    Remède

    Nommez les colonnes manuellement ou référence par index:

     
    dgvBooks.Columns(0).Visible = True
    

    Exemple 2: faites attention au NewRow

     
    xlWorkSheet = xlWorkBook.Sheets("sheet1")
    
    For i = 0 To myDGV.RowCount - 1
        For j = 0 To myDGV.ColumnCount - 1
            For k As Integer = 1 To myDGV.Columns.Count
                xlWorkSheet.Cells(1, k) = myDGV.Columns(k - 1).HeaderText
                xlWorkSheet.Cells(i + 2, j + 1) = myDGV(j, i).Value.ToString()
            Next
        Next
    Next
    

    Lorsque votre DataGridView a AllowUserToAddRows comme True (valeur par défaut), le Cells dans la ligne vide /nouvelle en bas contiendra tous Nothing. La plupart des tentatives d'utilisation du contenu (par exemple, ToString) aboutissent à un message NRE.

    Remède

    Utilisez une boucle For/Each et testez la propriété IsNewRow pour déterminer s'il s'agit de la dernière ligne. Cela fonctionne que AllowUserToAddRows soit vrai ou non:

     
    For Each r As DataGridViewRow in myDGV.Rows
        If r.IsNewRow = False Then
             ' ok to use this row
    

    Si vous utilisez une boucle For n, modifiez le nombre de lignes ou utilisez Exit For lorsque IsNewRow est vraie.

    My.Settings (StringCollection)

    Dans certaines circonstances, essayer d'utiliser un élément de My.Settings qui est un StringCollection peut entraîner un NullReference la première fois que vous l'utilisez. La solution est la même, mais pas aussi évidente. Considérez:

     
    My.Settings.FooBars.Add("ziggy")         ' foobars is a string collection
    

    Etant donné que VB gère les paramètres pour vous, il est raisonnable de s’attendre à ce qu’il initialise la collection. Ce sera le cas, mais seulement si vous avez déjà ajouté une entrée initiale à la collection (dans l'éditeur de paramètres). Étant donné que la collection est (apparemment) initialisée lorsqu'un élément est ajouté, il reste Nothing lorsqu'il n'y a aucun élément dans l'éditeur de paramètres à ajouter.

    Remède

    Initialisez la collection de paramètres dans le gestionnaire d'événements Load du formulaire, si nécessaire -

     
    If My.Settings.FooBars Is Nothing Then
        My.Settings.FooBars = New System.Collections.Specialized.StringCollection
    End If
    

    Généralement, la collection Settings n'aura besoin d'être initialisée que lors de la première exécution de l'application. Une autre solution consiste à ajouter une valeur initiale à votre collection dans Projet - > Paramètres | FooBars , enregistrez le projet, puis supprimez la fausse valeur.

    Points clés

    Vous avez probablement oublié l'opérateur New.

    ou

    Quelque chose que vous avez supposé fonctionnerait parfaitement pour renvoyer un objet initialisé à votre code, ne l'a pas été.

    N'ignorez jamais les avertissements du compilateur et utilisez Option Strict On (toujours).

    Exception MSDN NullReference

        
    300
    2018-07-18 06: 31: 45Z

    Un autre scénario consiste à convertir un objet null en un type de valeur . Par exemple, le code ci-dessous:

     
    object o = null;
    DateTime d = (DateTime)o;
    

    Il lancera un NullReferenceException sur le casting. Cela semble assez évident dans l'exemple ci-dessus, mais cela peut se produire dans des scénarios plus complexes "à liaison tardive" où l'objet nul a été renvoyé à partir d'un code que vous ne possédez pas, et la conversion est par exemple générée par un système automatique.

    Un exemple typique est ce simple fragment de liaison ASP.NET avec le contrôle Calendar:

     
    <asp:Calendar runat="server" SelectedDate="<%#Bind("Something")%>" />
    

    Ici, SelectedDate est en fait une propriété - de type DateTime - du type Calendar Web Control, et la liaison pourrait parfaitement renvoyer une valeur null. Le générateur ASP.NET implicite créera un morceau de code qui sera équivalent au code de distribution ci-dessus. Et cela soulèvera un NullReferenceException assez difficile à repérer, car il se trouve dans du code généré par ASP.NET qui compile bien ...

        
    224
    2018-07-18 06: 28: 37Z
    1. Bonne prise. Manière uniqueéviter: DateTime x = (DateTime) o as DateTime? ?? defaultValue;
      2015-06-29 11: 07: 14Z

    Cela signifie que la variable en question n’est pointée du tout. Je pourrais générer ceci comme suit:

     
    SqlConnection connection = null;
    connection.Open();
    

    Cela jettera l’erreur car, bien que j’ai déclaré la variable "connection", elle ne pointe pas vers rien. Lorsque j'essaie d'appeler le membre "Open", il n'y a aucune référence à résoudre, et l'erreur sera renvoyée.

    Pour éviter cette erreur:

    1. Initialisez toujours vos objets avant d'essayer de faire quoi que ce soit avec eux.
    2. Si vous ne savez pas si l'objet est null, vérifiez-le avec object == null.

    L'outil Resharper de JetBrains identifie chaque emplacement de votre code pouvant comporter une erreur de référence null, ce qui vous permet d'activer un contrôle nul. Cette erreur est la source de bogues numéro un, IMHO.

        
    156
    2015-06-10 10: 01: 00Z
    1. L'outil Resharper de JetBrains identifiera tous les emplacements de votre code susceptibles de contenir une erreur de référence nulle. Ceci est incorrect. J'ai une solution sans cette détection, pourtant le code est parfois exceptionnel. Je soupçonne que c'est parfois indétectable - du moins chez eux - lorsque le multithreading est impliqué, mais je ne peux pas en dire davantage, car je n'ai pas encore identifié l'emplacement de mon bug.
      2018-01-21 07: 42: 30Z
    2. Mais comment le résoudre quand l'exception NullReferenceException arrive en utilisant HttpContext.Current.Responce.Clear (). Aucune des solutions ci-dessus ne résout le problème. Une erreur survient lors de la création de l'objet objet de HttpContext. "La résolution de la surcharge a échoué car aucun" Nouveau "accessible n'accepte ce nombre d'arguments.
      2018-02-02 11: 14: 26Z

    Cela signifie que votre code a utilisé une variable de référence d'objet définie sur null (c'est-à-dire qu'il ne faisait pas référence à une instance d'objet réelle).

    Pour éviter cette erreur, les objets pouvant être null doivent être testés avant d'être utilisés.

     
    if (myvar != null)
    {
        // Go ahead and use myvar
        myvar.property = ...
    }
    else
    {
        // Whoops! myvar is null and cannot be used without first
        // assigning it to an instance reference
        // Attempting to use myvar here will result in NullReferenceException
    }
    
        
    152
    2014-07-28 19: 17: 10Z

    Sachez que, quel que soit le scénario, la cause est toujours la même dans .NET:

      

    Vous essayez d'utiliser une variable de référence dont la valeur est Nothing/null. Lorsque la valeur de la variable de référence est Nothing/null, cela signifie qu'elle ne contient pas réellement de référence à une instance d'un objet quelconque existant sur le segment de mémoire.

         

    Vous n’avez jamais assigné quelque chose à la variable, jamais créé une instance de la valeur affectée à la variable, ou vous avez défini la variable sur Nothing/null manuellement, ou vous avez appelé une fonction qui a défini la variable sur Nothing/null pour vous.

        
    95
    2015-06-10 10: 03: 19Z

    Voici un exemple de cette exception: lorsque vous essayez de vérifier quelque chose, il est nul.

    Par exemple:

     
    string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)
    
    if (testString.Length == 0) // Throws a nullreferenceexception
    {
        //Do something
    } 
    

    Le runtime .NET lève une exception NullReferenceException lorsque vous essayez d'effectuer une action sur quelque chose qui n'a pas été instancié, c'est-à-dire le code ci-dessus.

    En comparaison avec une exception ArgumentNullException qui est généralement émise à titre de mesure défensive si une méthode s’attend à ce que ce qui lui est transmis ne soit pas nul.

    Des informations complémentaires sont disponibles dans C # NullReferenceException et Null Parameter .

        
    86
    2018-07-18 06: 32: 31Z

    Si vous n'avez pas initialisé le type de référence et que vous souhaitez définir ou lire l'une de ses propriétés, une NullReferenceException sera lancée.

    Exemple:

     
    Person p = null;
    p.Name = "Harry"; // NullReferenceException occurs here.
    

    Vous pouvez simplement éviter cela en vérifiant si la variable n'est pas null:

     
    Person p = null;
    if (p!=null)
    {
        p.Name = "Harry"; // Not going to run to this point
    }
    

    Pour bien comprendre pourquoi une exception NullReferenceException est levée, il est important de connaître la différence entre types de valeur et types de référence .

    Ainsi, si vous avez affaire à des types de valeur , des exceptions NullReferenceExceptions peuvent ne pas se produire . Vous devez toutefois rester vigilant lorsque vous traitez avec des types de référence !

    .

    Seuls les types de référence, comme son nom l'indique, peuvent contenir des références ou ne pas pointer littéralement vers rien (ou "null"). Les types de valeur contiennent toujours une valeur.

    Types de référence (ceux-ci doivent être cochés):

    • dynamique
    • objet
    • chaîne

    Types de valeur (vous pouvez simplement les ignorer):

    • Types numériques
    • Types intégraux
    • Types à virgule flottante
    • décimal
    • bool
    • Structures définies par l'utilisateur
    83
    2018-07-18 06: 33: 04Z
    1. - 1: étant donné que la question est "Qu'est-ce qu'une exception NullReferenceException", les types de valeur ne sont pas pertinents.
      2013-05-16 22: 00: 50Z
    2. @ John Saunders: Je ne suis pas d'accord. En tant que développeur de logiciels, il est très important de pouvoir distinguer les types de valeur et de référence. sinon les gens finiront par vérifier si les entiers sont nuls.
      2013-05-16 22: 28: 20Z
    3. Vrai, mais pas dans le contexte de cette question.
      2013-05-16 22: 44: 05Z
    4. Merci pour cet indice. Je l'ai un peu amélioré et ajouté un exemple en haut. Je pense toujours à mentionner Reference & Les types de valeur sont utiles.
      2013-05-16 23: 02: 10Z
    5. Je pense que vous n'avez rien ajouté qui ne figure dans les autres réponses, car la question suppose un type de référence.
      2013-05-18 23: 24: 59Z

    Un autre cas où NullReferenceExceptions peut se produire est l'utilisation (incorrecte) de opérateur as :

     
    class Book {
        public string Name { get; set; }
    }
    class Car { }
    
    Car mycar = new Car();
    Book mybook = mycar as Book;   // Incompatible conversion --> mybook = null
    
    Console.WriteLine(mybook.Name);   // NullReferenceException
    

    Ici, Book et Car sont des types incompatibles; un Car ne peut pas être converti /converti en un Book. Lorsque cette distribution échoue, as renvoie null. Si vous utilisez mybook après cela, vous obtenez un NullReferenceException.

    En général, vous devez utiliser un casting ou as, comme suit:

    Si vous vous attendez à ce que la conversion de type réussisse toujours (par exemple, vous savez ce que l'objet devrait être à l'avance), vous devez utiliser un transtypage:

     
    ComicBook cb = (ComicBook)specificBook;
    

    Si vous n'êtes pas sûr du type mais que vous souhaitez essayer de l'utiliser comme type spécifique, utilisez as:

    .  
    ComicBook cb = specificBook as ComicBook;
    if (cb != null) {
       // ...
    }
    
        
    77
    2018-07-18 06: 33: 28Z
    1. Cela peut arriver souvent lorsque déballer une variable. Je constate que cela se produit souvent dans les gestionnaires d'événements après avoir modifié le type de l'élément d'interface utilisateur, mais j'ai oublié de mettre à jour le code-behind.
      2014-02-19 00: 24: 28Z

    Vous utilisez l'objet qui contains la référence de valeur null. Donc, cela donne une exception nulle. Dans l'exemple, la valeur de la chaîne est null et lors de la vérification de sa longueur, une exception s'est produite.

    Exemple:

     
    string value = null;
    if (value.Length == 0) // <-- Causes exception
    {
        Console.WriteLine(value); // <-- Never reached
    }
    

    L'erreur d'exception est:

      

    Exception non gérée:

         

    System.NullReferenceException: la référence d'objet n'est pas définie sur une instance   d'un objet. à Program.Main ()

        
    64
    2015-05-25 13: 41: 20Z
    1. Quelle profondeur! Je n'ai jamais considéré la constante 'nulle' comme une valeur de référence. C'est donc comme ça que C # extrait un "NullPointer" hein? Comme je me souviens en C ++, un NPE peut être provoqué par le déréférencement d'un pointeur non initialisé (c'est-à-dire, type de référence en c #) dont la valeur par défaut est une adresse qui n'est pas allouée à ce processus (dans de nombreux cas, 0, en particulier dans les versions ultérieures de C ++ qui effectuaient l’initialisation automatique, qui appartient au système d’exploitation - f avec lui et meurent (ou attrapez simplement le sigkill avec lequel le processus attaque votre processus)).
      2013-07-31 18: 55: 50Z

    Bien que ce qui provoque un NullReferenceExceptions et les approches pour eviter /corriger une telle exception ont été abordées dans d'autres réponses. Ce que de nombreux programmeurs n'ont pas encore appris, c'est comment déboguer ces exceptions lors du développement.

    Dans Visual Studio, cela est généralement facile grâce au débogueur de Visual Studio .

    Tout d’abord, assurez-vous que l’erreur correcte sera interceptée - voir Comment puis-je autoriser l'interruption de 'System.NullReferenceException' dans VS2010? Remarque 1 /em>

    Ensuite, Commencez par le débogage (F5) ou Joignez [le débogueur VS] au processus en cours . À l'occasion, il peut être utile d'utiliser Debugger.Break , qui vous invitera à lancer le débogueur.

    Maintenant, lorsque l’exception NullReferenceException est levée (ou non gérée), le débogueur s’arrête (rappelez-vous la règle définie ci-dessus?) sur la ligne sur laquelle l’exception s’est produite. Parfois, l'erreur sera facile à repérer.

    Par exemple, Dans la ligne suivante, le seul code que peut provoquer l'exception, si myString est évalué à null. Cela peut être vérifié en consultant la fenêtre de surveillance ou expressions en cours d’exécution dans la fenêtre immédiate .

     
    var x = myString.Trim();
    

    Dans les cas plus avancés, tels que les suivants, vous devrez utiliser l'une des techniques ci-dessus (fenêtres surveillées ou immédiates) pour inspecter les expressions afin de déterminer si str1 était nul ou si str2 était nul.

     
    var x = str1.Trim() + str2.Trim();
    

    Une fois que l'exception a été localisée, il est généralement trivial de raisonner à l'envers pour savoir où la valeur null a été [incorrectement] introduite -

    Prenez le temps nécessaire pour comprendre la cause de l'exception. Inspecter pour les expressions nulles. Inspectez les expressions précédentes qui auraient pu générer de telles expressions nulles. Ajoutez points d'arrêt et parcourez le programme comme il convient. Utilisez le débogueur.

    1 Si Break on Throws est trop agressif et que le débogueur s'arrête sur un NPE dans la bibliothèque .NET ou tierce, Interrompre le traitement par l'utilisateur , peut être utilisé pour limiter les exceptions interceptées. De plus, VS2012 introduit Just My Code que je recommande également d'activer.

      

    Si vous déboguez avec Just My Code activé, le comportement est légèrement différent. Lorsque Just My Code est activé, le débogueur ignore les exceptions CLR (Common Language Runtime) première chance quiRe jeté en dehors de Mon Code et ne pas passer par Mon Code

        
    62
    2018-07-18 06: 42: 11Z

    Simon Mourier a donné cet exemple :

     
    object o = null;
    DateTime d = (DateTime)o;  // NullReferenceException
    

    où une conversion unboxing (cast) à partir de object (ou à partir de l'une des classes System.ValueType ou System.Enum, ou à partir d'un type d'interface) to un type de valeur (autre que Nullable<>) lui-même donne le NullReferenceException.

    Dans l’autre sens, une conversion boxe de a Nullable<> qui a HasValue égal à false à a type référence, peut donner une référence null qui peut ensuite conduire à un NullReferenceException. L'exemple classique est:

     
    DateTime? d = null;
    var s = d.ToString();  // OK, no exception (no boxing), returns ""
    var t = d.GetType();   // Bang! d is boxed, NullReferenceException
    

    Parfois, la boxe se déroule d'une autre manière. Par exemple, avec cette méthode d’extension non générique:

     
    public static void MyExtension(this object x)
    {
      x.ToString();
    }
    

    le code suivant sera problématique:

     
    DateTime? d = null;
    d.MyExtension();  // Leads to boxing, NullReferenceException occurs inside the body of the called method, not here.
    

    Ces cas sont dus aux règles spéciales que le moteur d’exécution utilise lors de la mise en boîte des instances Nullable<>.

        
    57
    2018-07-18 06: 34: 19Z

    Ajout d'un cas où le nom de classe de l'entité utilisée dans la structure d'entité est identique au nom de classe d'un fichier code-behind de formulaire Web.

    Supposons que vous ayez un formulaire Web Contact.aspx dont la classe codebehind est Contact et que vous avez un nom d'entité Contact.

    Le code suivant lève une exception NullReferenceException lorsque vous appelez context.SaveChanges ()

     
    Contact contact = new Contact { Name = "Abhinav"};
    var context = new DataContext();
    context.Contacts.Add(contact);
    context.SaveChanges(); // NullReferenceException at this line
    

    Par souci d’exhaustivité, classe DataContext

     
    public class DataContext : DbContext 
    {
        public DbSet<Contact> Contacts {get; set;}
    }
    

    et la classe d'entité Contact. Parfois, les classes d'entités sont des classes partielles afin que vous puissiez les étendre également dans d'autres fichiers.

     
    public partial class Contact 
    {
        public string Name {get; set;}
    }
    

    L'erreur se produit lorsque l'entité et la classe codebehind se trouvent dans le même espace de noms. Pour résoudre ce problème, renommez la classe entity ou la classe codebehind pour Contact.aspx.

    Raison Je ne suis toujours pas sûr de la raison. Mais chaque fois que l'une des classes d'entités étendra System.Web.UI.Page, cette erreur se produit.

    Pour en savoir plus, consultez une exception NullReferenceException dans DbContext.saveChanges ()

    .     
    41
    2017-05-23 12: 34: 45Z

    Un autre cas général dans lequel cette exception peut être générée consiste à se moquer de classes pendant les tests unitaires. Quel que soit le cadre utilisé, vous devez vous assurer que tous les niveaux appropriés de la hiérarchie de classes sont correctement simulés. En particulier, toutes les propriétés de HttpContext qui sont référencées par le code testé doivent être simulées.

    Voir " NullReferenceException levée lors du test de AuthorizationAttribute personnalisé " pour un peu détaillé. exemple.

        
    40
    2017-05-23 12: 34: 45Z

    J'ai une perspective différente pour répondre à cette question. Ce type de réponses "Que puis-je faire d'autre pour l'éviter? "

    Lorsque vous travaillez sur plusieurs couches , par exemple dans une application MVC, un contrôleur a besoin de services pour appeler des opérations commerciales. Dans de tels scénarios, conteneur d'injection de dépendance peut être utilisé pour initialiser les services afin d'éviter l'exception NullReferenceException . Cela signifie donc que vous n'avez pas à vous soucier de la vérification de null et à simplement appeler les services du contrôleur comme s'ils étaient toujours disponibles (et initialisés) en tant que singleton ou prototype.

     
    public class MyController
    {
        private ServiceA serviceA;
        private ServiceB serviceB;
    
        public MyController(ServiceA serviceA, ServiceB serviceB)
        {
            this.serviceA = serviceA;
            this.serviceB = serviceB;
        }
    
        public void MyMethod()
        {
            // We don't need to check null because the dependency injection container 
            // injects it, provided you took care of bootstrapping it.
            var someObject = serviceA.DoThis();
        }
    }
    
        
    39
    2016-12-29 08: 44: 58Z
    1. - 1: cette main uniqueles un seul scénario - celui des dépendances non initialisées. Ceci est un scénario minoritaire pour NullReferenceException. La plupart des cas sont un simple malentendu sur le fonctionnement des objets. Viennent ensuite les situations où le développeur a supposé que l’objet serait initialisé automatiquement.
      2014-03-07 00: 06: 17Z
    2. Tous les autres ont déjà obtenu une réponse ci-dessus.
      2014-03-07 00: 23: 32Z
    3. L'injection de dépendance n'est généralement pas utilisée pour éviter NullReferenceException. Je ne crois pas que vous ayez trouvé un scénario général ici. Dans tous les cas, si vous modifiez votre réponse pour qu'elle soit davantage dans le style de stackoverflow.com/a/15232518/76337 , alors je retirerai le vote négatif.
      2014-03-07 00: 30: 09Z

    À propos de "que dois-je faire à ce sujet" , les réponses peuvent être multiples.

    Un moyen plus "formel" d'éviter de telles conditions d'erreur en cours de développement consiste à appliquer conception par contrat dans votre code. Cela signifie que vous devez définir des invariants de classe , et /ou même une fonction /méthode des préconditions et des postconditions sur votre système, tout en développant.

    En bref, les invariants de classe garantissent que votre classe contiendra des contraintes qui ne seront pas violées en utilisation normale (et par conséquent, la classe ne sera pas un état incohérent). Préconditions signifie que les données fournies en entrée d'une fonction /méthode doivent respecter certaines contraintes et que jamais ne les respecte pas, et postconditions signifie qu'une fonction /La sortie de la méthode doit à nouveau respecter les contraintes définies sans jamais les violer. Les conditions du contrat doivent ne jamais être respectées lors de l'exécution d'un programme exempt de bogues. Par conséquent, la conception par contrat est vérifiée en pratique en mode débogage, tout en étant désactivé dans les versions , afin de maximiser la performances système développées.

    De cette façon, vous pouvez éviter NullReferenceException cas résultant d’une violation du jeu de contraintes. Par exemple, si vous utilisez une propriété d'objet X dans une classe et essayez ultérieurement d'appeler l'une de ses méthodes et que X a une valeur null, cela entraînera NullReferenceException:

     
    public X { get; set; }
    
    public void InvokeX()
    {
        X.DoSomething(); // if X value is null, you will get a NullReferenceException
    }
    

    Mais si vous définissez "la propriété X ne doit jamais avoir une valeur null" comme condition préalable à la méthode, vous pouvez empêcher le scénario décrit précédemment:

     
    //Using code contracts:
    [ContractInvariantMethod]
    protected void ObjectInvariant () 
    {
        Contract.Invariant ( X != null );
        //...
    }
    

    Pour cette raison, Code Les contrats existent pour les applications .NET.

    Vous pouvez également appliquer la conception par contrat à l'aide de assertions .

    MISE À JOUR: Il convient de mentionner que ce terme a été inventé par Bertrand Meyer en relation avec sa conception du langage de programmation Eiffel .

        
    37
    2016-12-30 15: 56: 42Z
    1. J'ai pensé ajouter ceci car personne ne l'a mentionné, et dans la mesure où cela existe en tant qu'approche, mon intention était d'enrichir le sujet.
      2014-12-26 01: 03: 01Z
    2. Merci d'avoir enrichi le sujet. J'ai donné mon avis sur votre ajout. Maintenant, d'autres peuvent faire la même chose.
      2014-12-26 01: 05: 44Z
    3. Je pensais que c'était un ajout intéressant au sujet, étant donné qu'il s'agit d'un fil très consulté. J'ai déjà entendu parler de contrats de code et c'était un bon rappel pour envisager de les utiliser.
      2015-01-08 02: 03: 57Z

    Un NullReferenceException est lancé quand nous sommesessayant d'accéder aux propriétés d'un objet null ou lorsqu'une valeur de chaîne devient vide et que nous essayons d'accéder à des méthodes de chaîne.

    Par exemple:

    1. Lorsqu'une méthode de chaîne d'une chaîne vide est utilisée:

       
      string str = string.Empty;
      str.ToLower(); // throw null reference exception
      
    2. Lors de l'accès à une propriété d'un objet null:

       
      Public Class Person {
          public string Name { get; set; }
      }
      Person objPerson;
      objPerson.Name  /// throw Null refernce Exception 
      
    35
    2015-06-10 06: 04: 10Z
    1. Ceci est incorrect. String.Empty.ToLower() ne lève pas d'exception de référence nulle. Il représente une chaîne réelle, bien qu’elle soit vide (c’est-à-dire ""). Etant donné que cela a un objet sur lequel appeler ToLower(), il ne serait pas logique de lancer une exception de référence null à cet endroit.
      2015-07-24 06: 00: 35Z

    TL; DR: essayez d’utiliser Html.Partial au lieu de Renderpage

    Je recevais Object reference not set to an instance of an object lorsque j'ai essayé de rendre une vue dans une vue en lui envoyant un modèle, comme suit:

     
    @{
        MyEntity M = new MyEntity();
    }
    @RenderPage("_MyOtherView.cshtml", M); // error in _MyOtherView, the Model was Null
    

    Le débogage a montré que le modèle était Null dans MyOtherView. Jusqu'à ce que je le change en:

     
    @{
        MyEntity M = new MyEntity();
    }
    @Html.Partial("_MyOtherView.cshtml", M);
    

    Et cela a fonctionné.

    De plus, la raison pour laquelle je n'avais pas Html.Partial pour commencer était parce que Visual Studio parfois jette des lignes ondulées ressemblant à une erreur sous Html.Partial si elle se trouve dans une boucle foreach construite différemment, même si ce n'est pas vraiment le cas. une erreur:

     
    @inherits System.Web.Mvc.WebViewPage
    @{
        ViewBag.Title = "Entity Index";
        List<MyEntity> MyEntities = new List<MyEntity>();
        MyEntities.Add(new MyEntity());
        MyEntities.Add(new MyEntity());
        MyEntities.Add(new MyEntity());
    }
    <div>
        @{
            foreach(var M in MyEntities)
            {
                // Squiggly lines below. Hovering says: cannot convert method group 'partial' to non-delegate type Object, did you intend to envoke the Method?
                @Html.Partial("MyOtherView.cshtml");
            }
        }
    </div>
    

    Mais j’ai pu exécuter l’application sans aucun problème avec cette "erreur". J'ai pu supprimer l'erreur en modifiant la structure de la boucle foreach afin qu'elle ressemble à ceci:

     
    @foreach(var M in MyEntities){
        ...
    }
    

    Bien que j'ai le sentiment que c'est parce que Visual Studio a mal interprété les esperluettes et les crochets.

        
    30
    2016-05-16 08: 35: 52Z
    1. Vous vouliez Html.Partial et non @Html.Partial
      2015-07-24 13: 55: 45Z
    2. Indiquez également quelle ligne a lancé l'exception et pourquoi.
      2015-07-24 13: 56: 53Z
    3. L'erreur s'est produite dans MyOtherView.cshtml, ce que je n'ai pas inclus ici, car le modèle n'a pas été envoyé correctement (c'était Null). Je connaissais donc l'erreur. était avec la façon dont j'envoyais le modèle.
      2015-07-27 11: 44: 53Z

    Que pouvez-vous faire à ce sujet?

    Il y a beaucoup de bonnes réponses ici expliquant ce qu'est une référence nulle et comment la déboguer. Mais il y a très peu de choses sur la façon de prévenir le problème ou au moins de le rendre plus facile à attraper.

    Vérifier les arguments

    Par exemple, les méthodes peuvent vérifier les différents arguments pour voir s'ils sont nuls et renvoyer une ArgumentNullException, une exception créée à cet effet.

    Le constructeur du ArgumentNullException prend même le nom du paramètre et un message comme arguments afin que vous puissiez indiquer exactement au développeur le problème.

     
    public void DoSomething(MyObject obj) {
        if(obj == null) 
        {
            throw new ArgumentNullException("obj", "Need a reference to obj.");
        }
    }
    

    Utiliser les outils

    Plusieurs bibliothèques peuvent également vous aider. "Resharper", par exemple, peut vous envoyer des avertissements lorsque vous écrivez du code, en particulier si vous utilisez leur attribut: NotNullAttribute

    Il existe des "contrats de code Microsoft" dans lesquels vous utilisez une syntaxe telle que Contract.Requires(obj != null), qui vous donne le contrôle de l'exécution et de la compilation: Présentation des contrats de code .

    Il existe également "PostSharp" qui vous permettra d'utiliser uniquement des attributs tels que:

     
    public void DoSometing([NotNull] obj)
    

    En faisant cela et en faisant de PostSharp une partie de votre processus de construction, obj sera vérifiée pour la valeur null lors de l'exécution. Voir: vérification null de PostSharp .

    Solution de code simple

    Ou vous pouvez toujours coder votre propre approche en utilisant du code ancien et clair. Par exemple iciest une structure que vous pouvez utiliser pour intercepter des références nulles. Il est calqué sur le même concept que Nullable<T>:

     
    [System.Diagnostics.DebuggerNonUserCode]
    public struct NotNull<T> where T: class
    {
        private T _value;
    
        public T Value
        {
            get
            {
                if (_value == null)
                {
                    throw new Exception("null value not allowed");
                }
    
                return _value;
            }
            set
            {
                if (value == null)
                {
                    throw new Exception("null value not allowed.");
                }
    
                _value = value;
            }
        }
    
        public static implicit operator T(NotNull<T> notNullValue)
        {
            return notNullValue.Value;
        }
    
        public static implicit operator NotNull<T>(T value)
        {
            return new NotNull<T> { Value = value };
        }
    }
    

    Vous utiliseriez de la même manière que vous utiliseriez Nullable<T>, sauf dans le but de réaliser exactement le contraire - ne pas autoriser null. Voici quelques exemples:

     
    NotNull<Person> person = null; // throws exception
    NotNull<Person> person = new Person(); // OK
    NotNull<Person> person = GetPerson(); // throws exception if GetPerson() returns null
    

    NotNull<T> est implicitement transtypé vers et à partir de T afin que vous puissiez l'utiliser pratiquement partout où vous en avez besoin. Par exemple, vous pouvez transmettre un objet Person à une méthode prenant un NotNull<Person>:

     
    Person person = new Person { Name = "John" };
    WriteName(person);
    
    public static void WriteName(NotNull<Person> person)
    {
        Console.WriteLine(person.Value.Name);
    }
    

    Comme vous pouvez le voir ci-dessus avec nullable, vous accéderiez à la valeur sous-jacente via la propriété Value. Vous pouvez également utiliser une conversion explicite ou implicite. Vous pouvez voir un exemple avec la valeur de retour ci-dessous:

     
    Person person = GetPerson();
    
    public static NotNull<Person> GetPerson()
    {
        return new Person { Name = "John" };
    }
    

    Ou vous pouvez même l'utiliser lorsque la méthode retourne T (dans ce cas, Person) en effectuant un transtypage. Par exemple, le code suivant aimerait simplement le code ci-dessus:

     
    Person person = (NotNull<Person>)GetPerson();
    
    public static Person GetPerson()
    {
        return new Person { Name = "John" };
    }
    

    Combinaison avec extension

    Combinez NotNull<T> avec une méthode d’extension pour couvrir davantage de situations. Voici un exemple de ce à quoi la méthode d’extension peut ressembler:

     
    [System.Diagnostics.DebuggerNonUserCode]
    public static class NotNullExtension
    {
        public static T NotNull<T>(this T @this) where T: class
        {
            if (@this == null)
            {
                throw new Exception("null value not allowed");
            }
    
            return @this;
        }
    }
    

    Et voici un exemple d'utilisation de cet outil:

     
    var person = GetPerson().NotNull();
    

    GitHub

    Pour votre information, le code ci-dessus est disponible sur GitHub. Vous pouvez le trouver à l'adresse suivante:

    https://github.com/luisperezphd/NotNull

    Fonctionnalité de langage associée

    C # 6.0 a introduit "l'opérateur null-conditionnel" qui aide un peu à cela. Grâce à cette fonctionnalité, vous pouvez référencer des objets imbriqués. Si l'un d'entre eux correspond à null, l'expression entière renvoie null.

    Ceci réduit le nombre de vérifications nulles que vous devez faire dans certains cas. La syntaxe est de mettre un point d'interrogation avant chaque point. Prenez le code suivant par exemple:

     
    var address = country?.State?.County?.City;
    

    Imaginez que country soit un objet de type Country qui possède une propriété appelée State et ainsi de suite. Si country, State, County ou City est null, alors address will be null . Therefore you only have to check whether adresse is null`.

    C’est une fonctionnalité intéressante, mais elle vous donne moins d’informations. Cela ne permet pas de déterminer lequel des 4 est nul.

    Intégré comme Nullable?

    C # a un joli raccourci pour Nullable<T>, vous pouvez rendre quelque chose annulable en mettant un point d’interrogation après le type comme int?.

    Ce serait bien si C # avait quelque chose comme la structure NotNull<T> ci-dessus et un raccourci similaire, peut-être le point d’exclamation (!) afin que vous puissiez écrire quelque chose comme: public void WriteName(Person! person).

        
    22
    2017-10-29 09: 06: 44Z
    1. Ne lancez jamais NullReferenceException
      2016-03-06 20: 35: 21Z
    2. @ JohnSaunders ose-je demander pourquoi? (Sérieusement mais pourquoi?)
      2016-03-07 15: 29: 30Z
    3. NullReferenceException doit être levée par le CLR. Cela signifie qu'une référence à une valeur nulle a eu lieu. Cela ne signifie pas qu’une référence à un null se produirait, à moins que vous ayiez habilement vérifié en premier.
      2016-03-07 15: 43: 52Z
    4. Je vois ce que vous dites à propos de la confusion qui peut en résulter. Je l'ai mis à jour avec une exception régulière pour cet exemple et une exception personnalisée dans GitHub.
      2016-03-07 18: 41: 52Z
    5. Excellente réponse à une question aussi fondamentale. Ce n'est pas si grave quand c'est votre code qui échoue. C’est horrible de voir le contenu d’une bibliothèque tierce commerciale sur laquelle vous comptez, et l’assistance client insiste pour que ce soit votre code qui cause le problème. Et vous n'êtes pas tout à fait sûr que ce ne soit pas le cas et le projet dans son ensemble est sur le point de s’arrêter. Je pense en fait que cela pourrait constituer un épitaphe approprié à ma tombe: "La référence à un objet n’est pas définie sur une instance d’objet."
      2016-05-03 04: 01: 06Z

      Vous pouvez corriger l'erreur NullReferenceException de manière claire à l'aide d'opérateurs Null-conditionnels en c # 6 et écrire moins de code pour gérer les contrôles NULL.

      Il est utilisé pour tester la valeur null avant d'effectuer un accès membre (?.) ouopération d'index (? [).

      Exemple

       
        var name = p?.Spouse?.FirstName;
      

      est équivalent à:

       
          if (p != null)
          {
              if (p.Spouse != null)
              {
                  name = p.Spouse.FirstName;
              }
          }
      

      Le résultat est que le nom sera null lorsque p est null ou lorsque p.Spouse est null.

      Sinon, le nom de la variable se verra attribuer la valeur de p.Spouse.FirstName.

      Pour plus de détails: Null- Opérateurs conditionnels

          
      9
      2017-11-29 23: 19: 36Z

      La ligne d'erreur "Référence d'objet non définie sur une instance d'objet. "indique que vous n’avez pas affecté d’objet d’instance à une référence d’objet et que vous continuez d’accéder aux correctes /méthodes de cet objet.

      Par exemple: supposons que vous ayez une classe appelée myClass et qu'elle contienne une propriété prop1.

       
      public Class myClass
      {
         public int prop1 {get;set;}
      }
      

      Vous accédez maintenant à ce prop1 dans une autre classe, comme ci-dessous:

       
      public class Demo
      {
           public void testMethod()
           {
              myClass ref = null;
              ref.prop1 = 1;  //This line throws error
           }
      }
      

      la ligne ci-dessus renvoie une erreur car la référence de la classe myClass est déclarée mais n'est pas instanciée ou une instance d'objet n'est pas affectée au référent de cette classe.

      Pour résoudre ce problème, vous devez instancier (attribuer un objet à la référence de cette classe).

       
      public class Demo
      {
           public void testMethod()
           {
              myClass ref = null;
              ref = new myClass();
              ref.prop1 = 1;  
           }
      }
      
          
      8
      2017-03-08 10: 58: 18Z
      1. Cette réponse a déjà été répondue.
        2017-03-08 11: 31: 26Z

      Fait intéressant, aucune des réponses sur cette page ne mentionne les deux cas extrêmes, espérons que cela ne dérange personne si je les ajoute:

      Cas n ° 1: accès simultané à un dictionnaire

      Les dictionnaires génériques dans .NET ne sont pas thread-safe et ils peuvent parfois jeter un NullReference ou même (plus fréquemment) un KeyNotFoundException lorsque vous essayez d'accéder à une clé à partir de deux threads simultanés. L’exception est assez trompeuse dans ce cas.

      Cas n ° 2: code non sécurisé

      Si un code NullReferenceException est renvoyé par le code unsafe, vous pouvez examiner vos variables de pointeur et les rechercher pour IntPtr.Zero ou quelque chose du genre. Ce qui est la même chose ("exception de pointeur nul"), mais dans le code peu sûr, les variables sont souvent transtypées en types de valeur /tableaux, etc. exception.

      (Une autre raison de ne pas utiliser de code non sécurisé sauf si vous en avez besoin, soit dit en passant)

          
      8
      2017-04-19 00: 08: 28Z
      1. Votre exemple de dictionnaire n'est pas un cas particulier. Si l'objet n'est pas thread-safe, son utilisation à partir de plusieurs threads produit des résultats aléatoires. Votre exemple de code non sécurisé diffère de null en quoi?
        2017-03-24 02: 03: 11Z

      NullReferenceException ou Référence d'objet non définie à une instance d'objet se produit lorsqu'un objet de la classe que vous essayez d'utiliser n'est pas instancié. Par exemple:

      Supposons que vous ayez une classe nommée Student.

       
      public class Student
      {
          private string FirstName;
          private string LastName;
          public string GetFullName()
          {
              return FirstName + LastName;
          }
      }
      

      Maintenant, considérez un autre cours dans lequel vous essayez de récupérer le nom complet de l'étudiant.

       
      public class StudentInfo
      {      
          public string GetStudentName()
          {
              Student s;
              string fullname = s.GetFullName();
              return fullname;
          }        
      }
      

      Comme indiqué dans le code ci-dessus, la déclaration Student s : déclare uniquement la variable de type Student. Notez que la classe Student n'est pas instanciée à ce stade. Par conséquent, lorsque l'instruction s.GetFullName () est exécutée, une exception NullReferenceException est générée.

          
      3
      2016-07-28 10: 52: 34Z

      Eh bien, en termes simples:

      Vous essayez d'accéder à un objet qui n'est pas créé ou actuellement en mémoire.

      Alors, comment y remédier:

      1. Déboguer et laisser le débogueur se briser ... Il prendra directementPour vous connecter à la variable qui est cassée ... Maintenant, votre tâche consiste simplement à résoudre ce problème. Utilisez le nouveau mot clé à l'emplacement approprié.

      2. Si cela est provoqué par certaines commandes database parce que l'objet n'est pas présent, il vous suffit de procéder à une vérification null et de le gérer:

         
        if (i == null) {
            // Handle this
        }
        
      3. Le plus difficile .. si le GC a déjà collecté l'objet ... Cela se produit généralement si vous essayez de trouver un objet à l'aide de chaînes ... Autrement dit, si vous le recherchez par son nom, il peut arriver que le CPG l'ait déjà nettoyé. .. C’est difficile à trouver et deviendra un véritable problème ... Une meilleure façon de s’y attaquer est de faire des contrôles nuls chaque fois que cela est nécessaire pendant le processus de développement. Cela vous fera gagner beaucoup de temps.

      En cherchant par nom, je veux dire que certains frameworks vous permettent de FIndObjects en utilisant des chaînes et que le code pourrait ressembler à ceci: FindObject ("ObjectName");

          
      2
      2016-05-16 08: 34: 08Z
      1. Si vous avez une référence à un objet, le CPG ne le nettoie jamais
        2015-12-24 07: 51: 46Z
      2. si vous utilisez des objets tels que FindObject ("nom d'objet"), GC ne saura pas avant de savoir que vous allez refernece cet objet .. c'est ce que est-ce qui essayait d'explaing .. ceux-ci se produisent à l'exécution
        2015-12-24 08: 11: 04Z
      3. Certains frameworks fournissent cette fonctionnalité en C #, tels que Unity. la question n'a rien à voir avec BCl. Effectuez une recherche sur Internet avant de critiquer, il existe une tonne de fonctions comme celles-ci et, pour votre gentilles informations, je l'utilise même quotidiennement. Dites-moi maintenant comment la réponse n’a aucun sens.
        2015-12-24 12: 35: 24Z
      4. docs .unity3d.com /ScriptReference /… vérifiez le lien et corrigez-le mr.expert: p
        2015-12-24 12: 54: 12Z
      5. Les exemples que j'ai vus dans votre lien attribuent les résultats de GameObject.Find à un champ membre. C'est une référence et le GC ne la collectera pas tant que l'objet contenant ne sera pas collecté.
        2016-05-25 18: 00: 40Z

      Si nous considérons des scénarios courants dans lesquels cette exception peut être levée, accéder aux propriétés avec un objet en haut.

      Ex:

       
      string postalcode=Customer.Address.PostalCode; 
      //if customer or address is null , this will through exeption
      

      ici, si adresse est null, vous obtiendrez NullReferenceException.

      Donc, comme pratique, nous devrions toujours utiliser le contrôle null avant d'accéder aux propriétés de tels objets (spécialement en générique)

       
      string postalcode=Customer?.Address?.PostalCode;
      //if customer or address is null , this will return null, without through a exception
      
          
      0
      2017-08-24 05: 55: 22Z
      1. Il a déjà été répondu à plusieurs reprises.
        2017-08-26 03: 24: 14Z

      Littéralement, le moyen le plus simple de réparer une NullReferenceExeption comporte deux moyens. Si vous avez par exemple un objet GameObject avec un script et une variable nommée rb (rigidbody), cette variable commencera à zéro lorsque vous démarrez votre jeu.
      C'est pourquoi vous obtenez une NullReferenceExeption car l'ordinateur ne possède pas de données stockées dans cette variable.

      Je vais utiliser une variable RigidBody comme exemple.
      Nous pouvons ajouter des données très facilement de plusieurs manières:

      1. Ajoutez un RigidBody à votre objet avec AddComponent > Physique > Rigidbody
        Ensuite, allez dans votre script et tapez rb = GetComponent<Rigidbody>();
        Cette ligne de code fonctionne mieux avec vos fonctions Start() ou Awake().
      2. Vous pouvez ajouter un component par programme et assigne la variable en même temps avec une ligne de code: rb = AddComponent<RigidBody>();

      Notes complémentaires: si vous souhaitez que one ajoute un composant à votre objet et que vous en ayez oublié un, vous pouvez taper [RequireComponent(typeof(RigidBody))] au-dessus de votre déclaration de classe (l'espace situé au-dessous de toutes vos utilisations).
      Profitez et amusez-vous à faire des jeux!

          
      0
      2017-11-14 20: 45: 02Z

      Si l’on reçoit ce message lors de l’enregistrement ou de la compilation, il suffit de fermer tous les fichiers, puis d’ouvrir tout fichier à compiler et à enregistrer.

      Pour moi, la raison était que j'avais renommé le fichier et que l'ancien fichier était toujours ouvert.

          
      - 1
      2017-10-14 18: 48: 08Z

      Pour utiliser les méthodes et les membres d'un objet, vous devez d'abord créer cet objet. Si vous ne l'avez pas créé (la variable qui doit contenir l'objet n'est pas initialisé), mais que vous essayez d'utiliser ses méthodes ou variables, vous obtiendrez cette erreur.

      Parfois, vous avez peut-être oublié d'initialiser.

      Modifié: new ne peut pas renvoyer null, mais déclencher l'exception en cas d'échec. Il y a longtemps, c'était le cas dans certaines langues, mais plus maintenant. Merci à John Saunders de l'avoir signalé.

          
      - 1
      2017-10-27 13: 56: 19Z
      1. new ne renvoie jamais la valeur null
        2017-10-27 13: 00: 04Z

      Il s'agit essentiellement d'une exception de référence Null . En tant que Microsoft états-

        

      Une exception NullReferenceException est levée lorsque vous essayez d'accéder à un   membre d'un type dont la valeur est null.

      Qu'est-ce que cela signifie?

      Cela signifie que si un membre ne détient aucune valeur et que nous lui demandons d’exécuter certaines tâches, le système lancera sans aucun doute un message et dira:

      "Hé, attendez, ce membre n'a pas de valeur et ne peut donc pas exécuter la tâche à laquelle vous le confiez."

      L'exception elle-même indique que quelque chose est référé mais dont la valeur n'est pas définie. Cela signifie donc que cela se produit uniquement lors de l'utilisation de types de référence, car les types de valeur ne sont pas nullables.

      NullReferenceException ne se produira pas si nous utilisons des membres de type Value.

       
      class Program
      {
          static void Main(string[] args)
          {
              string str = null;
              Console.WriteLine(str.Length);
              Console.ReadLine();
          }
      }
      

      Le code ci-dessus indique une chaîne simple à laquelle est attribuée une valeur null .

      Désormais, lorsque j'essaie d'imprimer la longueur de la chaîne str , j'obtiens Une exception non gérée du type 'System.NullReferenceException' s'est produite car un membre str pointe vers null et il ne peut y avoir aucune longueur de null.

      " NullReferenceException " se produit également lorsque vous oubliez d'instancier un type de référence.

      Supposons que j'ai une méthode de classe et de membre. Je n'ai pas instancié ma classe, mais seulement nommé ma classe. Maintenant, si j'essaie d'utiliser la méthode, le compilateur émettra une erreur ou émettra un avertissement (selon le compilateur).

       
      class Program
      {
          static void Main(string[] args)
          {
              MyClass1 obj;
              obj.foo();  //Use of unassigned local variable 'obj'
          }
      }
      
      public class MyClass1
      {
          internal void foo()
          {
              Console.WriteLine("hello from foo");
      
          }
      }
      

      Le compilateur du code ci-dessus génère une erreur indiquant que la variable obj n'est pas affectée, ce qui signifie que notre variable a des valeurs NULL ou rien. Le compilateur du code ci-dessus génère une erreur selon laquelle la variable obj n'est pas affectée, ce qui signifie que notre variable a des valeurs NULL ou rien.

      Pourquoi cela se produit?

      • Une exception NullReferenceException est due à notre faute pour ne pas avoir vérifié la valeur de l'objet. Nous laissons souvent les valeurs d'objet décochées dans le développement du code.

      • Cela se produit également lorsque nous oublions d'instancier nos objets. L'utilisation de méthodes, propriétés, collections, etc., qui peuvent renvoyer ou définir des valeurs null peut également être à l'origine de cette exception.

      Comment peut-on l'éviter?

      Il existe différents moyens et méthodes pour éviter cette exception renommée:

      1. Vérification explicite: nous devrions adhérer à la traditionf vérifier si les objets, propriétés, méthodes, tableaux et collections sont nuls. Ceci peut être simplement implémenté en utilisant des instructions conditionnelles comme if-else if-else, etc.

      2. Gestion des exceptions: L’un des moyens les plus importants de gérer cette exception. En utilisant de simples blocs try-catch-finally, nous pouvons contrôler cette exception et en conserver un journal. Cela peut être très utile lorsque votre application est en phase de production.

      3. Opérateurs nuls: Null, les opérateurs conditionnels et les opérateurs conditionnels null peuvent également être utilisés lors de la définition de valeurs pour des objets, des variables, des propriétés et des champs.

      4. Débogueur: Pour les développeurs, nous avons la grande arme du débogage avec nous. Si nous faisons face à une exception NullReferenceException lors de la phase de développement, nous pouvons utiliser le débogueur pour accéder à la source de l'exception.

      5. Méthode intégrée: Des méthodes système telles que GetValueOrDefault (), IsNullOrWhiteSpace () et IsNullorEmpty () recherchent des valeurs null et attribuent la valeur par défaut s'il existe une valeur null.

      Il y a déjà beaucoup de bonnes réponses ici. Vous pouvez également consulter une description plus détaillée avec des exemples sur mon blog .

      J'espère que cela aide aussi!

          
      - 2
      2017-10-18 07: 31: 02Z
      1. En gros, vous avez copié la moitié de cet article de blog et n'ajoutez rien de nouveau que les réponses existantes n'abordent pas.
        2017-07-18 14: 41: 29Z
      2. @ codecaster Est-il dit de le copier lorsque vous récrivez un résumé de votre propre blog. Je sais qu'il n'y a rien de nouveau dans ma réponse et rien de nouveau que les réponses précédentes n'ont pas, mais je souhaite contribuer de manière plus sophistiquée et laisser les autres comprendre la façon dont j'ai compris. Sera heureux même si cela aide une seule personne. De bonne foi.
        2017-07-18 18: 01: 29Z

      Il existe un scénario lié à Classe . La question a fini par être fermée avant que je déclare la résolution: https://stackoverflow.com/questions/43348009/unable-to-instantiate-class"> https://stackoverflow.com/questions/43348009/unable-to-instantiate-class

      Méfiez-vous des classes qui n'instancient pas: si une partie de votre constructeur dans une classe jette un null reference exception, la classe n'instancie pas. Dans mon cas, il essayait d'obtenir une chaîne de connexion à partir du web.config qui n'existait pas.

      J'ai instancié une classe:

       
      ClassName myClass = new ClassName();
      myClass.RunSomeMethod();
      

      Dans la classe elle-même, il y avait un appel pour obtenir une chaîne de connexion du web.config. Cette partie du constructeur a généré une exception de valeur NULL. myClass était donc null.

      Si vous rencontrez un jour une classe qui ne s’instancie pas, essayez de vous assurer qu’aucune partie du constructeur de la classe ne lance un null value exception. F-11 et parcourez la classe et assurez-vous qu'il n'y a pas de valeur NULL.

          
      - 5
      2017-05-23 10: 31: 36Z
      1. Les constructeurs ne renvoient jamais la valeur null. Ils instancient un objet ou lèvent une exception.
        2017-04-11 21: 12: 13Z
      2. @ CodeCaster J'ai reformulé toute la réponse, en espérant pouvoir répondre à vos préoccupations. Le point étant que je n'ai pas vu dans d'autres réponses, c'est que si une partie du constructeur de la classe lève une exception, la classe ne sera pas instanciée. Bien que cela ait beaucoup de sens pour moi, cela ne m'a pas semblé un choix évident.
        2017-04-12 16: 13: 26Z
      3. Encore une fois, cela ne peut pas arriver. Si ce constructeur lance, la ligne suivante ne sera pas exécutée.
        2017-04-13 05: 32: 54Z
      4. @ logixologist Totalement d'accord avec CC ici, cette réponse n'a aucun sens en tant que telle.
        2017-07-0512: 36: 38Z
source placée ici