none
Nullreferenz bei eigener Klasse & mit new RRS feed

  • Frage

  •   public class State
      {
        public State(string name)
        {
          this.Name = name;
        }
        public string Name;
      }
    

    Habe diese Klasse gemacht und dann hier verwendet:

          State S1 = new State("S1");
          State S2 = new State("S2");
          State SE = new State("SE");
    
          Signal h = new Signal("h");
          Signal a = new Signal("a");
    
          Transition hS1 = new Transition();
          hS1.Source = S1;
          hS1.Destination = S2;
          hS1.onSignal = h;
    
          StateMachine s = new StateMachine();
          s.States.Add(S1);
    
    Bekomme beim Versuch, S1 zur Liste hinzuzufügen eine NullReferenceExeption. Weiß jemand warum?

    Freitag, 5. November 2010 11:10

Antworten

  • Hallo Alex,

    NullReferenceException-Ausnahmefehler sind meist leicht zu debuggen. In den Details des Ausnahmeassistenten kann man sich den StackTrace ansehen und entdeckt dabei sehr einfach die verursachende Codezeile, sowie die Aufruferkette. In dem von Dir grob umrissenen Fall ist es tatsächlich wahrscheinlich, dass die State-Liste zu der hinzugefügt werden soll (s.States) noch nicht instanziiert wurde. Das ist schnell behoben: Ein List<State> _list = new List<State>() und schon kann's weitergehen. Aber nicht immer ist es so einfach, die Ursache zu erkennen.

    Das Problem besteht darin, dass NullReferenceException nicht vom Compiler aufgefangen werden und sich nur während der Laufzeit eines Programms ereignen. Das eröffnet viele Fehlermöglichkeiten, die nicht offensichtlich sind. Man kann den Fehler nur beim Debuggen entdecken, und da er oft in tiefer Aufrufhierarchie versteckt ist, fällt es dem Programmierer bei der Durchsicht des Testcodes nicht sofort auf. Multiplizier diese Situation mit der Anzahl der Stellen, die in einem Programm auf null gesetzt werden können, und Du wirst sehen, was ich meine, wenn ich sage, dass die NullReferenceException ein großes Problem beim Erstellen von qualitativem Code ist.

    Abhilfe kommt in Form eines Tools von Microsoft Research, ein Visual Studio Add-in das im Projektdesigner eine neue Registerkarte hinzufügt: Code Contracts (Codeverträge). Wenn man hier die Option Perform Static Contract Checking und die Unteroption Implicit Non-Null Obligations ankreuzt, wird beim Kompilieren Deines Codes z.B. folgende Warnung ausgegeben:

    Warnung 1 - CodeContracts: Possibly calling a method on a null reference 's.States' C:\Users\[Username]\documents\visual studio 2010\Projects\ConsoleApplication8\ConsoleApplication8\Program.cs 25 13 ConsoleApplication8

    Fehler beim Kompilieren entdecken statt zur Laufzeit! Das ist außerordentlich praktisch: Ein Doppelklick auf die Warnung und man landet in der betroffenen Codezeile.

    Noch ein Hinweis am Ende: Die CodeContract Tools gibt es sowohl für VS2008 als auch für VS2010. Ab .NET 4.0 sind die Codeverträge im Framework integriert.


    Microsoft Research - CodeContract Tools
    http://research.microsoft.com/en-us/downloads/4ed7dd5f-490b-489e-8ca8-109324279968/default.aspx

    Codeverträge
    http://msdn.microsoft.com/de-de/library/dd264808.aspx


    Gruß
    Marcel

    Samstag, 6. November 2010 17:41
    Moderator
  • Vermutlich ist "s.States" == null
    Freitag, 5. November 2010 11:31
  • Hallo IA.,

    typischerweise vergisst man bei Auflistungen leicht, dass diese initialisiert werden müssen/sollten.

    Hier eine mögliche Lösung:

     public class StateMachine
     {
        public List<State> States { get; set; }
    
        public StateMachine()
        {
          States = new List<State>(); 
        }
    // . . . }

    ciao Frank
    Samstag, 6. November 2010 15:57

Alle Antworten

  • Vermutlich ist "s.States" == null
    Freitag, 5. November 2010 11:31
  • Hallo IA.,

    typischerweise vergisst man bei Auflistungen leicht, dass diese initialisiert werden müssen/sollten.

    Hier eine mögliche Lösung:

     public class StateMachine
     {
        public List<State> States { get; set; }
    
        public StateMachine()
        {
          States = new List<State>(); 
        }
    // . . . }

    ciao Frank
    Samstag, 6. November 2010 15:57
  • Hallo Alex,

    NullReferenceException-Ausnahmefehler sind meist leicht zu debuggen. In den Details des Ausnahmeassistenten kann man sich den StackTrace ansehen und entdeckt dabei sehr einfach die verursachende Codezeile, sowie die Aufruferkette. In dem von Dir grob umrissenen Fall ist es tatsächlich wahrscheinlich, dass die State-Liste zu der hinzugefügt werden soll (s.States) noch nicht instanziiert wurde. Das ist schnell behoben: Ein List<State> _list = new List<State>() und schon kann's weitergehen. Aber nicht immer ist es so einfach, die Ursache zu erkennen.

    Das Problem besteht darin, dass NullReferenceException nicht vom Compiler aufgefangen werden und sich nur während der Laufzeit eines Programms ereignen. Das eröffnet viele Fehlermöglichkeiten, die nicht offensichtlich sind. Man kann den Fehler nur beim Debuggen entdecken, und da er oft in tiefer Aufrufhierarchie versteckt ist, fällt es dem Programmierer bei der Durchsicht des Testcodes nicht sofort auf. Multiplizier diese Situation mit der Anzahl der Stellen, die in einem Programm auf null gesetzt werden können, und Du wirst sehen, was ich meine, wenn ich sage, dass die NullReferenceException ein großes Problem beim Erstellen von qualitativem Code ist.

    Abhilfe kommt in Form eines Tools von Microsoft Research, ein Visual Studio Add-in das im Projektdesigner eine neue Registerkarte hinzufügt: Code Contracts (Codeverträge). Wenn man hier die Option Perform Static Contract Checking und die Unteroption Implicit Non-Null Obligations ankreuzt, wird beim Kompilieren Deines Codes z.B. folgende Warnung ausgegeben:

    Warnung 1 - CodeContracts: Possibly calling a method on a null reference 's.States' C:\Users\[Username]\documents\visual studio 2010\Projects\ConsoleApplication8\ConsoleApplication8\Program.cs 25 13 ConsoleApplication8

    Fehler beim Kompilieren entdecken statt zur Laufzeit! Das ist außerordentlich praktisch: Ein Doppelklick auf die Warnung und man landet in der betroffenen Codezeile.

    Noch ein Hinweis am Ende: Die CodeContract Tools gibt es sowohl für VS2008 als auch für VS2010. Ab .NET 4.0 sind die Codeverträge im Framework integriert.


    Microsoft Research - CodeContract Tools
    http://research.microsoft.com/en-us/downloads/4ed7dd5f-490b-489e-8ca8-109324279968/default.aspx

    Codeverträge
    http://msdn.microsoft.com/de-de/library/dd264808.aspx


    Gruß
    Marcel

    Samstag, 6. November 2010 17:41
    Moderator