2009-05-07 6 views
0

Ich habe etwas Code, der etwas sehr ähnliches tut, die gleiche Idee wirklich ... Erstellen einer Variablen, versuchen, es zu initialisieren, dann testen, um zu sehen, ob die Initialisierung ein Erfolg war.C# Initialisierung Verwirrung!

von Visual Studios mir einen Fehler geben sagen: „Die Verwendung von nicht zugewiesenen lokalen Variablen‚test‘“, die Art von ärgerlich ist, diese leicht durch Einstellen der ersten Zeile festgelegt ist:

int? test = null; 

aber ich bin gespannt was der Unterschied zwischen den beiden Zeilen ist, denn der Compiler scheint sich wirklich darum zu kümmern. Und nach meinem besten Wissen machen die beiden Linien das Gleiche.

+3

OT, aber FWIW ... möchten Sie vielleicht in TryParse() – Shog9

+0

Ich bin nicht wirklich mit diesem Code verwenden, das ist nur ein Szenario, dass ich scheinen hin und wieder zu laufen. – Meiscooldude

Antwort

5

Das Problem ist der Catch-Block. Der Compiler muss davon ausgehen, dass der Int32.Parse-Code den catch-Block auslösen und somit treffen kann. In diesem Fall wird die Zeile "Int32.Parse" nicht abgeschlossen und daher wird test nie ein Wert zugewiesen. Das bedeutet, dass die Zeile "if" versucht, einen nicht initialisierten Wert zu verwenden.

Sie können dieses Problem beheben, indem

  1. Test zuordnen Wert im catch-Block
  2. es auf null zu Beginn des Verfahrens initialisieren
1

Sie den Unterschied sind verwirrend zwischen dem, was ist eine Variablendeklaration und was ist Variableninitialisierung

int? test; 

simpl y besagt, dass Sie eine Variable mit dem Namen Test haben, dass ein Nullable-int

ist

aber

int? test = null; 

besagt, dass Sie eine Variable mit dem Namen Test haben, der ein Nullable-int und sein Wert ist null

In VB Es gibt keinen Unterschied, aber in C# gibt es einen Unterschied. Deshalb beschwert sich der Compiler, denn wenn in Ihrem try-Block etwas fehlschlägt, wäre Ihre Testvariable niemals initialisiert worden.

0

Sie tun das gleiche, Sie sind korrekt, jedoch erfordert die Variable die explizite Zuweisung von Null, um den Fehler 'nicht zugewiesener Wert' loszuwerden, wenn Sie möchten, dass null als absichtliche 'nicht gesetzte' Variable betrachtet wird Warnungen werfen. Darüber hinaus ist Jaredpars Antwort genau richtig.

1

Dies ist ein Fehler, der immer bei lokal definierten Variablen auftritt (innerhalb einer Methode oder Eigenschaft und nicht direkt in der Klasse). Obwohl die Tatsache bleibt, dass der Compiler muss nicht diesen Fehler erzeugen, um zu arbeiten, es tut es speziell für den Zweck, Ihnen zu helfen, potenziell unerwartete Ergebnisse im Falle der nicht immer Ihre Variablen zuweisen. (Jemand korrigiert mich, wenn ich falsch liege, aber zumindest einige frühere Versionen des C# -Compilers haben in einigen/allen Fällen nicht nach nicht zugewiesenen Variablen gesucht.)

Äquivalent (anstatt test = null in der Deklaration zuzuweisen), Sie könnte den Fehler beseitigen, indem test = null im catch-Block assigniert wird, da dies bedeuten würde, dass, egal welchen Pfad der Code nimmt, die Variable test zugewiesen wird.Ich denke jedoch, dass die Auflösung, die Sie angegeben haben (in der Deklaration null zuzuweisen), die richtige ist - Sie werden es sehr oft im C# -Code sehen, der sehr häufig auftritt (über try-catch-Anweisungen, if-Anweisungen oder was auch immer)) - und um ehrlich zu sein, hilft es Ihnen nur zu erkennen, was und wann Sie Ihre Variablen zuweisen, auch wenn es wie eine kleine Irritation erscheint. (? Int)

+3

Diese Antwort ist meistens falsch, obwohl sie zu einer korrekten Schlussfolgerung führt. Erstens sind Nullwert-Typen Werttypen, keine Referenztypen. Zweitens muss _reference types_ kein Wert zugewiesen werden. _ Lokale Variablen_ müssen einen Wert zugewiesen bekommen, bevor Sie sie verwenden. Drittens gibt es keine Möglichkeit, diesen Fehler im Compiler auszuschalten. Die Schlussfolgerung - dass die lokale Variable vor ihrer Verwendung definitiv zugewiesen werden muss - ist richtig, aber die Schlussfolgerung wird durch falsche Argumentation erreicht. –

+1

@ eric-lippert: Ja, mein Verstand funktionierte eindeutig nicht, als ich das schrieb. Ich habe versucht zu unterscheiden, wann und wann Sie nicht müssen Variablen zuweisen, bevor Sie sie verwenden (die richtige Bedingung ist für * alle * lokale Variablen, aber nicht Instanz/statische). Ein Großteil meiner Erklärung war dem Hauptargument ohnehin ein wenig tangential, so dass mein Punkt, dass der Fehler generiert wurde, um mögliche Fehlerquellen zu identifizieren, immer noch richtig ist. – Noldorin

+0

@ ric-lippert: Auch Referenztypen * do * müssen vor der Verwendung einen Wert zugewiesen bekommen, wenn sie lokal deklariert werden. Haben Sie sich auf eine andere Situation bezogen? – Noldorin

1

Sie können vermeiden gegossen, 7 Byte speichern für "= null" string :)

test = Int32.Parse ("7"); 
0

ich diesen Stil glauben ist viel sauberer:

try 
{ 
    int test = Int32.Parse("7"); 
    Console.WriteLine("Success!"); 
    // add return statement for successful execution here, if any 
} 
catch 
{ 
    Console.WriteLine("Disaster!"); 
    // other return statement here, if any 
} 

Wie für die Compilerfehler: Jedes lokale Feld muss vor dem Lesen explizit in einem Codepfad initialisiert werden. Es ist ein häufiger Fehler, lokale Felder nicht zu initialisieren, deshalb ist es ein Fehler in C#. C/C++ warnt nur davor und kann * lustige * Ergebnisse liefern, wenn es nicht initialisiert ist und der Wert die Bytes wiedergibt, die bereits auf dem Aufrufstapel waren.

Ich kann nur darüber spekulieren, aber es könnte ein Leistungsaspekt sein, lokale Felder im Gegensatz zu Klassenfeldern explizit zu initialisieren: Wenn ein Objekt instanziiert wird, ist es weniger kostspielig, den Objektspeicherstrom einmal zu initialisieren Das Initialisieren eines lokalen Felds bei jedem Methodenaufruf ist jedoch redundant.