Frage

Ich habe etwas Eigenartiges über Visual Studio bemerkt. Zuerst versuchen, diese (C #) eingeben irgendwo in einer Funktion:

class Foo  
{  
    public void Bar()  
    {  
        string s;
        int i = s.Length;
    }
}

Jetzt sofort wird es die s in s.Length als Fehler markiert, sagen „Use of unassigned local variable 's'“. Auf der anderen Seite, versuchen Sie diesen Code ein:

class Foo  
{  
    private string s;
    public void Bar()  
    {  
        int i = s.Length;
    }
}

Es wird kompilieren, und die s in private string s mit einer Warnung unterstreichen, sagen "Field 'Foo.s' is never assigned to, and will always have its default value null".

Nun, wenn VS dass smart ist und weiß, dass s immer null sein, warum ist es nicht ein Fehler seine Länge im zweiten Beispiel zu bekommen? Meine ursprüngliche Vermutung war: „Es gibt nur einen Compiler-Fehler, wenn der Compiler einfach nicht seine Aufgabe abgeschlossen werden kann. Da der Code technisch so lange läuft, wie Sie nie Bar () aufrufen, es ist nur eine Warnung.“ Mit Ausnahme dieser Erklärung wird durch das erste Beispiel für ungültig erklärt. Sie könnten noch so lange den Code ohne Fehler ausgeführt, wie Sie nie Bar () aufrufen. Also, was soll das? Nur ein Versehen, oder bin ich etwas fehlt?

War es hilfreich?

Lösung

Das erste Beispiel (der Fehler) ist ein Beispiel für die Compilers definitive Zuweisung Tracking und das ist nur auf lokale Variablen angelegt. Aufgrund der begrenzten Kontext hat der Compiler einen luftdichten Griff auf diese Situation. Beachten Sie, dass s nicht null ist, ist es nicht definiert ist.

Im zweiten Beispiel ist s ein Feld (und standardmäßig auf null). Es gibt keinen Compiler-Fehler, aber es wird immer zur Laufzeit gefangen werden. Dieser Fall könnte gefangen werden, aber diese Art von Fehler ist in der Regel nicht nachweisbar durch den Compiler.
Zum Beispiel könnten Sie eine Methode Bar2() hinzufügen, die eine Zeichenkette, die es als s später Bar() weisen aber zu rufen, oder gar nicht. Das würde die Warnung beseitigt aber nicht die Laufzeitfehler.

So ist es durch Design.

Andere Tipps

Für das zweite Beispiel der Code gültig ist, es könnte einfach nicht richtig laufen. Hier sind mehrere Fälle, in denen dieses Programm ausführen kann „erfolgreich“

  • Der Compiler ist nicht 100% richtig. Es ist möglich, „s“, um einen Nicht-Null-Wert zu haben, wenn eine Instanz durch Reflexion geändert wird.
  • Das Programm kann ohne Fehler ausgeführt werden, wenn das Verfahren Bar ist nicht immer genannt
  • Dieses Programm könnte ein Testprogramm sein, das eine Nullreferenceexception zu Testzwecken auslöst

Die einzige Vermutung die ich machen kann, ist, dass in dem zweiten Beispiel, s durch Reflexion geändert werden (unter Verwendung von BindingFlags.Private das privaten Mitglied zuzugreifen).

In erster Probe s ist eine lokale Variable und Compiler-Check easialy können, dass s varible nicht zugewiesen wurde, bevor es verwendet wird.

In der zweiten, s ist eine globale Variable und es ist möglich, dass es irgendwo anders in einer Klasse initialisiert wurde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top