2010-11-19 5 views
2

diesen Code-Snippet Gegeben:Behält der VS2008-Debugger Objekte außerhalb des Gültigkeitsbereichs?

// Get first key // 
int? keyEDISecurity = this.WorkQueue.GetNextWorkItem(); 

// Done? // 
while (keyEDISecurity != null) 
{ 
    try 
    { 

     ... 

     // Write changes // 
     List<ISNLEditableObject> changedRows = this.WorkQueue.GetChangedRows((int)keyEDISecurity); 
     this.Writer.Write(changedRows, WriteFlags.Transactional); 

     ... 
    } 
    catch (Exception ex) 
    { 
     // Exception handling/logging code 
    } 
    finally 
    { 
     // Remove all data for the KeyEDISecurity from work queue cache // 
     this.WorkQueue.RemoveData((int)keyEDISecurity); 
    } 

    // Get next work item // 
    keyEDISecurity = this.WorkQueue.GetNextWorkItem(); 
} 

vor der Zeile mit der Deklarationsliste changedRows ist changedRows null, wie es sein sollte. Es geht dann außer Reichweite, wenn Sie das nächste Arbeitselement erhalten. Dann kommst du zurück und vor dieser Zeile solltest du, wenn du auf "changedRows" zugreifst, wieder Null sein, da es nicht deklariert wurde.

Wenn Sie brechen und bearbeiten, dann können Sie wie erwartet nicht auf "changedRows" zugreifen, da der Gültigkeitsbereich überschritten wurde und noch nicht deklariert wurde. Wenn Sie es auswerten (entweder durch MouseOver oder mithilfe des unmittelbaren Fensters), haben Sie Zugriff auf die geändertenRows der vorherigen Iteration der Schleife. WTH?

Wer hat das gesehen? Es wirkt sich nicht auf das Programm aus, da es im Code korrekt zu funktionieren scheint, aber das Debugger-Problem verursachte Zeitverschwendung, da es sich nicht wie erwartet verhalten hat. Ich habe mich gefragt, ob das erwartetes Verhalten war oder nicht, damit ich es in Zukunft wissen und keine Zeit damit verschwenden könnte.

Antwort

6

Dies ist eine implementierungsspezifische Optimierung.

Wenn die Funktion ausgeführt wird, werden normalerweise alle Variablen auf dem Stapel gleichzeitig erstellt. Obwohl die Sprache es noch nicht erlaubt, auf sie zuzugreifen, sind sie da. Aus diesem Grund ist changedRowsnull bevor es überhaupt deklariert wurde.

Wenn die Variable den Gültigkeitsbereich verlässt, erlaubt die Sprache nicht, sie erneut zu verwenden, aber sie befindet sich immer noch auf dem Stapel. Der Wert muss nicht in null geändert werden, da er nirgendwo verwendet wird. Es wird Prozessorzeit verschwenden. Deshalb wird der Wert changedRows beibehalten, obwohl er gemäß den Sprachregeln zerstört werden muss (wenn er den Gültigkeitsbereich verlässt) und erneut erstellt wird (wenn er deklariert wird).

Der Debugger respektiert nicht alle Sprachregeln. In der Tat kann es sogar durch einige Konstrukte verwirrt werden. Wenn Sie versuchen, den Wert einer Variablen abzurufen, überprüft der Debugger nicht, ob er sich im Bereich usw. befindet.

Verwandte Themen