Frage

Nach dem mit einem Iteratorblock experimentieren bemerkte ich das erzeugte IL-Code ist nicht das, was ich erwarte, dass es sein. Statt einem Try-finally-Block Try-Fehlerblock erzeugt wird, die ich noch nie gesehen. Ich bemerkte, dass der Compiler nicht erlaubt ich in ‚handschriftlich‘ C #, um den Fehler Schlüsselwort.

Gibt es einen Unterschied zwischen den 2?

C # -Code:

static IEnumerable<string> ReadAllLines(string fileName)
{
    using (var file = System.IO.File.OpenText(fileName))
    {
        string s;
        while ((s = file.ReadLine()) != null)
        {
            yield return s;
        }
    }
}

MSIL Code:

.method private hidebysig newslot virtual final instance bool MoveNext() cil managed
{
    .override [mscorlib]System.Collections.IEnumerator::MoveNext
    .maxstack 3
    .locals init (
        [0] bool CS$1$0000,
        [1] int32 CS$4$0001,
        [2] string CS$0$0002,
        [3] bool CS$4$0003)
    L_0000: ldarg.0 

    // try body

    L_008d: leave.s L_0097
    L_008f: ldarg.0 
    L_0090: call instance void ConsoleApplication2.Program/<ReadAllLines>d__0::System.IDisposable.Dispose()
    L_0095: nop 
    L_0096: endfinally 
    L_0097: nop 
    L_0098: ldloc.0 
    L_0099: ret 
    .try L_0000 to L_008f fault handler L_008f to L_0097
}

Die interessante Zeile ist die letzte Zeile des IL, wo ein Fehler-Handler angegeben wird, wo in einem normalen try-finally ein Block schließlich Handler angegeben ist.

War es hilfreich?

Lösung

Ja, ein Finally-Block führt immer am Rahmen zu verlassen. Ein Fehlerblock wird nur ausgeführt, wenn eine Ausnahme hinter dem Rahmen abgewickelt wird. Der Fehlerblock in Movenext bewahrt die Verwendung von Semantik für den Fall einer Ausnahme von dem Try-Block des Iterators ReadAllLines geworfen. Ein anderer Mechanismus in Gebrauch sein muss, die mit Semantik auf normalen Austritt aus dem Iterator zu bewahren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top