2013-09-01 5 views
8

Der Artikel http://blogs.msdn.com/b/dotnet/archive/2009/08/25/the-good-and-the-bad-of-exception-filters.aspx schlägt vor, dass F # native unterstützt Ausnahmefilter (die zum Beispiel keine Syntax in C# haben). Ausnahmefilter führen vor den entsprechenden catch-Block aus, und wenn sie true zurückgeben, wird der catch-Block ausgeführt. Ich könnte mir vorstellen, F # tut dies mit so etwas wie diesesF # Exception Filter

with 
    | ex when filter(ex) -> printfn "Caught" 

aber für mich ist es zu den üblichen kompiliert „catch [mscorlib] System.Object“ mit einem Aufruf an die Filterfunktion innerhalb des catch-Block und kein „-Filter "Abschnitt ist in generierten MSIL vorhanden. Die Frage ist also, ob F # wirklich dieses Konstrukt unterstützt?

Dank

+1

Warum sind die Interna der Art und Weise, wie dies implementiert wird, für Sie von Bedeutung? –

+3

@JohnPalmer - die Implementierungsstrategie beeinflusst die Semantik in einigen Fällen (aufgrund des .NET/Windows-Zwei-Pass-Modells), also denke ich, dass es eine ziemlich relevante Frage ist. – kvb

+0

VB.NET und F # haben ähnliche konditionale Catch-Konstrukte, der VB.NET-Compiler gibt jedoch _filter_ blocks aus und F # scheint dies nicht zu tun. Dies macht die Semantik wichtig, wie @ kvb es formuliert hat, in einigen Fällen, besonders bei Interop – actionresult

Antwort

4

Soweit ich weiß, ist F # nicht tatsächlich umsetzen/Nutzung/aussetzen die filter verfügbar Handler in MSIL (ECMA-335, 5. Aufl., Partition I, Abschnitt 12.4.2 „Exception Handling "). Gemäß Abschnitt 6.9.21 der F# 3.0 language specification soll der Compiler die gesamte with-Klausel in einen catch-Block übersetzen; ein "Fall-Through" -Fall wird zu dem kompilierten Code hinzugefügt, so dass, wenn die gefangene Ausnahme keinem der Muster in der with-Klausel entspricht, sie erneut ausgelöst wird (über die IL-Anweisung rethrow).

Ich würde wirklich gerne sehen, F # mehr Low-Level-IL/CLR-Konstrukte zu unterstützen - sie werden nicht oft verwendet, aber manchmal bieten sie die einzige Möglichkeit, etwas richtig zu implementieren, oder sie vermeiden die Notwendigkeit für komplizierte Workarounds; und wie im Fall des OP ist es wichtig, dass F # diese für die Interoperabilität unterstützt. Zum Beispiel wäre try...fault wirklich nützlich für Protokollierungszwecke, und es würde einige Bits von Code vereinfachen, die derzeit try...finally mit zusätzlicher Logik verwenden müssen (z. B. die Implementierung von lock in FSharp.Core).

UPDATE: Ich suchte nur nach Informationen zu einem völlig anderen Thema und stieß auf diesen Beitrag von 2006 auf Don Blog: F# 1.1.13 now available! (siehe auch die begleitenden release notes). Natürlich war F # 1.1.13 eine frühe Version der Sprache, und zu diesem Zeitpunkt war es noch ziemlich experimentell, aber es ist interessant zu sehen, dass der Compiler einmal einen --generate-filter-blocks Switch hatte.