verstehe MSIL von try catch endlich

8

Ich habe den folgenden Code

%Vor%

Das aus dem obigen Code generierte MSIL lautet:

%Vor%

Ich habe folgende Fragen:

  1. Warum der try-catch wieder im try-Block enthalten ist.
  2. Es sieht so aus, als ob leave.s die letzte Zeile in try und catch Block ist Punkt, schließlich, d. h. IL_0010 aber an der Linie IL_0010 seine ldloc.1 was ich glaube Laden lokale Variable 1 auf dem Stapel, dann, wie es zeigt, um schließlich zu blockieren. Ist es so, als hätten wir an Adresse 1 die Adresse von finally block.
  3. Wenn ich etwas aus dem catch-Block werfe oder zurückgebe, wie kommt dann die Aufrufanweisung zum finally-Block, der bereits vom catch-Block zurückgegeben wurde, aber trotzdem der finally-Block ausgeführt wird.
Pankaj 22.12.2014, 11:24
quelle

2 Antworten

10
  

Warum der try-catch wieder im try-Block enthalten ist.

Nicht sicher in diesem Fall. Es kann nur sein, dass ildasm es dekompiliert. ECMA-335 sagt, es gibt Einschränkungen, wie SEHClause Elemente nach einem TryBlock angegeben werden können, aber ich habe diese Beschränkungen noch nicht gefunden.

  

Es sieht aus wie leave.s die letzte Zeile in try und catch Block ist Punkt, um schließlich dh IL_0010, aber an der Zeile IL_0010 seine ldloc.1 was ich glaube, laden lokale Variable 1 auf dem Stapel, dann, wie es zeigt, um schließlich zu blockieren . Ist es sowas wie an Ort 1 haben wir die Adresse von finally block.

Nein, das springt nach nach dem Block finally - um den Wert effektiv zurückzugeben. Es hilft nicht, dass Sie viele Return-Statements haben, die alle die gleiche Sache zurückgeben, wie auch nicht erreichbaren Code, aber ich glaube, der Punkt besteht im Grunde nur darin, das ret außerhalb des% zu verschieben. co_de% und try . Ich denke, der Compiler erstellt effektiv eine zusätzliche lokale Variable für den Rückgabewert.

  

Wenn ich etwas aus dem catch-Block werfe oder zurückgebe, wie kommt dann die Aufrufanweisung zum finally-Block, der bereits vom catch-Block zurückgegeben wurde, aber trotzdem der finally-Block ausgeführt wird.

So sind sowohl C # als auch IL definiert - der catch Block wird ausgeführt aber Sie verlassen den Block.

    
Jon Skeet 22.12.2014, 11:34
quelle
2

Jon Skeet hat die letzten beiden Fragen bereits beantwortet, also werde ich mich nur auf den ersten konzentrieren.

  

Warum der try-catch wieder im try-Block enthalten ist.

Dafür gibt es mehrere Gründe:

  • Wenn Sie den catch-Handler in den try-Block des finally-Handlers setzen, bedeutet dies, dass das finally auch dann stattfindet, wenn eine Ausnahme in den catch-Block geworfen wird (was meiner Meinung nach für die C # -Spezifikation erforderlich ist) direkte Bezugnahme auf, wo es so sagt).
  • Die CLI-Spezifikation hat einige strenge Regeln für überlappende Ausnahmebehandlungsbereiche, und diese Regeln schließen aus, dass die Catch- und finally-Blöcke den gleichen Code schützen, ohne dass der finally-Block auch den catch-Block oder den catch-Block schützt, auch den finally-Block (In der Spezifikation wird dies allgemeiner diskutiert. Sie finden die Details in Abschnitt 1, Abschnitt 12.4.2.7 von ECMA-335).
Brian Reichle 23.12.2014 15:29
quelle

Tags und Links