Erweitern Marks Antwort, lokale Initialisierung der Variablen bezieht sich auch auf den Verifizierungsprozess.
Die CLI erfordert, dass in jedem überprüfbaren Code (dh Module, die nicht ausdrücklich den Überprüfungsvorgang mit der SkipVerfication-Eigenschaft aus dem Attribut SecurityPermission übersprungen haben) alle lokalen Variablen vor der Verwendung initialisiert werden müssen. Andernfalls wird VerficationException ausgelöst.
Interessanter ist, dass der Compiler das .locals init
Flag automatisch auf jede Methode hinzufügt, die lokale Variablen verwendet. Dieses Flag bewirkt, dass der JIT-Compiler Code generiert, der alle lokalen Variablen auf ihre Standardwerte initialisiert. Das heißt, obwohl Sie sie bereits in Ihrem eigenen Code initialisiert haben, wird das JIT dem Flag .locals init
entsprechen und den richtigen Initialisierungscode generieren. Diese "doppelte Initialisierung" wirkt sich nicht auf die Leistung aus, da der JIT-Compiler in Konfigurationen, die Optimierungen ermöglichen, die Duplizierung erkennt und sie effektiv als "toten Code" behandelt (die automatisch generierte Initialisierungsroutine erscheint nicht in den generierten Assembler-Anweisungen).
Laut Microsoft (auch von Eric Lippert als Antwort auf eine Frage auf seinem Blog unterstützt), in den meisten Fällen, wenn Programmierer ihre lokale Variable nicht initialisieren, tun sie es nicht, weil sie auf der zugrundeliegende Umgebung, um ihre Variable auf ihre Standardwerte zu initialisieren, aber nur, weil sie "vergessen" haben und somit manchmal illusorische logische Fehler verursachen.
Um also die Wahrscheinlichkeit zu reduzieren, dass Fehler dieser Art im C# -Code auftreten, besteht der Compiler darauf, dass Sie Ihre lokalen Variablen initialisieren. Obwohl das Flag .locals init
dem generierten IL-Code hinzugefügt wird.
Eine ausführlichere Erklärung zu diesem Thema finden Sie hier: Behind The .locals init Flag
Das ist nur noch die Frage zu wiederholen. Aber warum? –
@YairHalberstadt das hängt davon ab, ob durch "warum?" man meint die Regel oder den Grund der Regel. Ich antwortete auf die erste, die wohl die Frage beantwortet; zum zweiten: weil man zu der Zeit, als man die Verkettung von Konstruktoren in Betracht gezogen hat, virtuelle Methoden während der Konstruktion aufgerufen hat und die Tatsache, dass auf der IL-Ebene Basiskonstruktoren an jeder Stelle der Aufrufkette aufgerufen werden können, fast unmöglich ist, etwas zu sagen sinnvoll bei Feldinitialisierung; Gleichermaßen können Felder überlappt werden, was es noch wichtiger macht, den Raum auf Null zu setzen, also ist kein Init technisch erforderlich - Kontrast ... –
@YairHalberstadt lokale Variablen, die eine sehr einfache Zuweisungsprüfung haben, wo uninitialisiert normalerweise einen Fehler bedeutet und wo wir kann die Nullstellung überspringen (obwohl die aktuelle Laufzeit dies nie tut, IIRC). –