2013-09-01 11 views
8

Artykuł http://blogs.msdn.com/b/dotnet/archive/2009/08/25/the-good-and-the-bad-of-exception-filters.aspx sugeruje, że F # natywnie obsługuje filtry wyjątków (które nie mają na przykład składni w języku C#). Filtry wyjątków uruchamiają odpowiedni blok catch, a jeśli zwrócą wartość true, blok catch zostanie wykonany. Mogę sobie wyobrazić, F # robi to przy użyciu coś takiegoFiltry wyjątków F #

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

Jednak dla mnie to kompiluje się zwykle „złapać [mscorlib] System.Object” przy wywołaniu funkcji filtra wewnątrz bloku catch i bez filtra” "Sekcja jest obecna w generowanym zbiorze MSIL. Pytanie brzmi, czy F # naprawdę wspiera tę konstrukcję?

Dzięki

+1

Dlaczego internals w sposobie, w jaki jest to realizowane, mają dla ciebie znaczenie? –

+3

@JohnPalmer - strategia implementacji faktycznie wpływa na semantykę w niektórych przypadkach narożnych (z powodu dwuprzebiegowego modelu .NET/Windows), więc myślę, że jest to dość istotne pytanie. – kvb

+0

VB.NET i F # mają podobne warunkowe konstrukcje catch, jednak kompilator VB.NET emituje _filter_ bloki, a F # najwyraźniej nie. To sprawia, że ​​semantyka ma znaczenie, jak to określił @kvb, w niektórych przypadkach, szczególnie w przypadku współpracy – actionresult

Odpowiedz

4

O ile mi wiadomo, F # nie rzeczywiście wdrożyć/używać/wystawiać filter teleskopowe dostępne w MSIL (ECMA-335, 5th Ed., Partycja I sekcja 12.4.2 „Obsługa wyjątków "). Zgodnie z sekcją 6.9.21 z F# 3.0 language specification, kompilator powinien skompilować całą klauzulę with do bloku catch; przypadek "fall-through" jest dodawany do skompilowanego kodu, więc jeśli wychwycony wyjątek nie pasuje do żadnego ze wzorów w klauzuli with, jest on ponownie podnoszony (za pomocą instrukcji IL rethrow).

Powiedziałbym, że bardzo chciałbym, aby F # wesprzeć konstrukcje IL/CLR niskiego poziomu - nie są one często używane, ale czasami stanowią jedyny sposób na prawidłowe wdrożenie lub unikają potrzeby dla skomplikowanych obejść; oraz, tak jak w przypadku PO, ważne jest, aby F # wspierał je dla celów interoperacyjności. Na przykład: try...fault byłby naprawdę przydatny do celów rejestrowania, a to uprościłoby niektóre fragmenty kodu, które obecnie muszą używać try...finally z dodatkową logiką (np. Implementacja lock w FSharp.Core).

UPDATE: Właśnie wyszukiwanie wokół dla informacji na zupełnie inny temat, i biegł tym stanowisku od 2006 roku na blogu Dona: F# 1.1.13 now available! (patrz także towarzyszący release notes). Oczywiście F # 1.1.13 był wcześniejszą wersją języka, i nadal był dość eksperymentalny, ale ciekawe jest, że kompilator miał kiedyś przełącznik --generate-filter-blocks.