2016-07-08 5 views
1

Sorry für die dumme Frage.Klassenmethoden: Soll ich Variablen immer überprüfen, bevor ich darauf zugreife?

Lassen Sie uns sagen, ich habe diese Klasse (Code ist in C#):

class Foo { 
    public List<string> Bars { get; set; }   
    public Foo() { } 
} 

Jetzt habe ich eine Methode implementieren möchten, dass einige Operationen auf Bars zum Beispiel Foo.Translate() zuführen.

Sollte ich immer überprüfen, dass das, was ich versuche zu ändern, nicht null oder gültig ist?

class Foo { 
    public List<string> Bars { get; set; }   
    public Foo() { } 

    public void Translate() 
    { 
     // Should I check with a null && count > 0? 
     if (Bars != null && Bars.Count > 0) 
     { 
      [...] 
     } 
    } 
} 
+0

Wenn 'Bars' jemals null ist, dann sollten Sie vor dem Zugriff darauf prüfen, ob es nicht null ist, da sonst eine Nullref-Ausnahme auftritt. Überprüfen, dass es nicht Null ist, ist jedoch Business-Logik .. – stuartd

+0

Nein, der Rest der 'Foo' Klasse sollte sicherstellen, dass Invariante zu jeder Zeit hält. – Lee

+0

'Bars' ist jedoch öffentlich, und eine andere Klasse könnte es auf null setzen. – stuartd

Antwort

5

Kommt drauf an.

Wenn der Wert null ist und es nicht sein sollte, ist offensichtlich etwas schiefgelaufen und was auch immer Sie tun ist jetzt ein ungültiges Szenario und wird Ihnen sowieso falsche Ergebnisse geben. Lass es die Ausnahme werfen. Überprüfen Sie die Protokolle, um herauszufinden, warum null ist, und beheben Sie diesen Fehler.

Wenn es sich um ein gültiges Szenario handelt, in dem der Wert null ist, wäre es angemessen, das zu tun, was Sie tun.

0

Es ist gängige Praxis Eigenschaften in Ihrem Konstruktor zu überprüfen und, wenn sie nicht gültig sind, eine Ausnahme zu werfen. Auf diese Weise können Sie garantieren, dass jedes Mal, wenn Sie diese Eigenschaft zugreifen sollte es in Ordnung sein. Und es ist auch gut, o die Immobilie mit eigenem Setter auf diese Weise nur der Konstruktor oder eine benutzerdefinierte Methode festlegen kann Ihre Klasse Eigenschaften aktualisieren.

0

Sie sollten Setter nie für Sammlungen freilegen (Es stellt Ihre Interna nach außen frei und es verletzt die Kapselung). Sie sollten Ihre Sammlung im Konstruktor initialisieren. Auf diese Weise wissen Sie, dass es niemals null sein wird.

Es gibt eine Code-Analyse-Warnung für diese - https://msdn.microsoft.com/en-us/library/ms182327.aspx

0

Es ist alles über Ihre Erwartungen. Wenn Sie erwarten, dass Foo eine Balkensammlung erfordert, lassen Sie den Benutzer diese im Konstruktor übergeben und validieren Sie sie dort (und machen Sie sie privat).

Wenn Sie erwarten, dass Bar innerhalb der Foo-Klasse aufgefüllt wird, sollten Sie sicherstellen, dass die Liste immer im Konstruktor instanziiert (und privat) wird. Das wird Null-Prüfungen vermeiden.

Wenn Sie erwarten, dass der Wert vor dem Ausführen einer Operation größer als 0 ist, sollten Sie vor dem Ausführen dieser Operation überprüfen, dass der Wert> 0 ist.

0

Da es ein Konstruktor im Code ist, kann ein Wert im Konstruktor für Nullwerte überprüft werden. Typischerweise wird, wenn der Wert erwartet wird, nicht null sein diese verwendet werden könnten:

class Foo { 
    public List<string> Bars { get; set; }   
    public Foo(string bars) { 
     try 
     { 
      if(bars == null){ bars = "" } //Whatever value bars should be if null, in this case an empty string. 
     { 
     catch(Exception) 
     { 
      throw; 
     } 

    } 
    public void Translate() 
    { 
     // Should I check with a null && count > 0? 
     if (Bars != null && Bars.Count > 0) 
     { 
      [...] 
     } 
    } 
} 

ich dies schneller glauben, als wenn das Objekt Foo instanziiert, werden alle NULL-Werte überprüft werden.

0

Sollte unter normalen Umständen niemals etwas null sein, überprüfen Sie nicht. Lassen Sie die Anwendung eine Ausnahme auslösen. Andernfalls, wenn Sie überprüfen zu tun und es ist null, was werden Sie tun? Sie könnten die null durch etwas anderes ersetzen, aber ist dieser Wert korrekt?

Aber der bessere Ansatz ist, den Zustand Ihrer Klassen mit eiserner Faust zu kontrollieren. Wenn List<string> Bars nicht null sein soll, nicht lassen Sie es null sein. Lassen Sie nicht zu, dass ein Objekt sich in einen ungültigen Zustand versetzt, und erlauben Sie anderen Objekten nicht, es in einen ungültigen Zustand zu versetzen. Wenn es nicht sein kannnull dann müssen Sie nicht überall überprüfen. null Überprüfungen überall sind eine Plage und ein Zeichen, dass wir nicht wissen, wie der Zustand unseres Codes ist.

In seiner einfachsten Form:

class Foo { 
    public List<string> Bars { get; } = new List<string>();  
    public Foo() { } 
} 

könnten Sie tun auch

class Foo { 
    private readonly List<string> _bars = new List<string>(); 
    public List<string> Bars { get { return _bars; } } 
    public Foo() { } 
} 

Jetzt _bars auf eine neue Liste gesetzt wird, wenn Foo erstellt wird und der Compiler wird verhindern, dass Sie immer _bars ändern. Sie können nur den Inhalt ändern. Nun, solange Sie mit dieser Klasse arbeiten, müssen Sie sich immer darum kümmern, ob _bars (oder durch die Erweiterung Bars) null ist.

Das gleiche gilt für Methoden, die Sammlungen oder andere Objekte zurückgeben. Wenn Sie nichts zurückgeben möchten, geben Sie nicht null zurück. Geben Sie ein leeres Array oder ein "leeres" Objekt zurück, mit dem die empfangende Methode harmlos arbeiten kann.

Verwandte Themen