Warum sollte C # lokale Variable direkt zugewiesen werden, selbst wenn es sich um einen Standardwert handelt?

8

Wenn Sie das nächste Beispiel betrachten:

%Vor%

Sie konnten leicht erkennen, dass die Variablen valueVariable und refType vor ihrer Verwendung in Console.WriteLine() nicht zugewiesen werden konnten. Der Compiler sagt uns das mit Fehlern:

%Vor%

Dies ist ein weit verbreiteter Fall und es gibt viele Antworten zur Fehlerbehebung das (mögliche Fixes kommentiert).

Was ich nicht verstehen kann ist warum solch ein Verhalten existiert? Wie unterscheiden sich hier lokale Variablen von Klassenfeldern , wobei die letzten Standardwerte erhalten werden, wenn sie nicht zugewiesen sind (null für Referenztypen und korrespondierender Standardwert für Werttypen)? Vielleicht gibt es ein Beispiel oder einen Eckfall, der erklärt, warum ein solches Compilerverhalten gewählt wurde?

    
Antonio 18.01.2014, 21:39
quelle

4 Antworten

11

grundsätzlich - das ist, was MS entschieden hat.

Wenn Sie mehr wollen, lesen Sie hier und Überprüfen Sie Eric Lipperts Blog

  

Der Grund, warum dies in C # illegal ist, liegt darin, dass die Verwendung eines nicht zugewiesenen Locals mit hoher Wahrscheinlichkeit ein Fehler ist.

    
Mzf 18.01.2014, 21:46
quelle
4

Es ist in c # spec beschrieben:

  

5.1.7 Lokale Variablen

     

Eine lokale Variable, die durch eine lokale Variablendeklaration eingeführt wird, ist dies nicht   automatisch initialisiert und hat somit keinen Standardwert. Für die   Zweck der eindeutigen Zuordnungsprüfung, eine lokale Variable eingeführt   durch eine lokale-Variable-Deklaration wird zunächst als nicht zugewiesen betrachtet. EIN    local-variable-declaration kann einen local-variable-initializer enthalten,   In diesem Fall wird die Variable nur als eindeutig zugewiesen betrachtet   nach dem Initialisierungsausdruck (§5.3.3.4).

     

Im Rahmen einer lokalen Variablen, die von a eingeführt wurde    local-variable-declaration , es ist ein Kompilierungsfehler, auf den verwiesen wird   Diese lokale Variable in einer textuellen Position, die ihr vorangeht    lokaler-Variable-Deklarator . Wenn die lokale Variablendeklaration ist   implizit (§8.5.1), ist es auch ein Fehler, auf die Variable innerhalb zu verweisen   sein lokaler-Variable-Deklarator .

    
MarcinJuraszek 18.01.2014 21:45
quelle
2

Wenn Sie etwas tun, das dumm erscheint , wie das Lesen von einer Variablen, die Sie noch nie zugewiesen haben, gibt es grundsätzlich zwei Dinge, die der Compiler tun kann:

  1. Gibt Ihnen eine Diagnose, die Sie darauf aufmerksam macht, was wahrscheinlich ein Fehler ist.
  2. Mach etwas Willkürliches.

Da Option # 1 hilft, Fehler zu finden, wird sie bevorzugt, besonders wenn die Umgehung des Compilers "Nein, ich meine den ursprünglichen Standardwert zu verwenden" einfach ist wie das Hinzufügen von = 0 , = null oder = default(T) .

Warum Klassenmitglieder nicht auf die gleiche Weise funktionieren, liegt daran, dass dies nicht zur Kompilierzeit überprüft werden kann (wegen der unzähligen verschiedenen Ordnungen, die die verschiedenen Methoden aufgerufen werden könnten). Es würde Laufzeitkosten von Flags geben, ob jedes Mitglied zugewiesen wurde, und Testen dieser Flags.

Beachten Sie, dass der Compiler die Einschränkung für Strukturelemente auf eine Weise erzwingt, die bei der Kompilierung einfach überprüft werden kann. Jeder Konstruktor muss nämlich jedes Mitglied zuweisen.

    
Ben Voigt 18.01.2014 21:49
quelle
0

In Wirklichkeit sollte Ihr Code in Ordnung sein, aber durch strenge Interpretation gibt es einen Code-Pfad, der Ihre Variablen vor der Verwendung nicht zugewiesen lassen kann. Der Block try führt die Möglichkeit ein, dass Code innerhalb des Blocks nicht ausgeführt wird (wenn eine Ausnahme ausgelöst wird), aber den Code weiterhin über catch hinaus ausführt (weil nichts vorhanden ist) in catch wie return oder throw , um zu verhindern, dass der Rest der Methode ausgeführt wird, wenn eine Ausnahme in try ).

Wenn Sie sich auf den Unterschied zwischen dem Initialisieren von "struct" -Feldern und dem Initialisieren von Klassenfeldern beziehen, zB:

%Vor%     
Zenilogix 18.01.2014 21:46
quelle