2013-09-01 136 views
8

文章http://blogs.msdn.com/b/dotnet/archive/2009/08/25/the-good-and-the-bad-of-exception-filters.aspx表明F#本地支持異常過濾器(例如,在C#中沒有語法)。異常過濾器在之前運行相應的catch塊,如果它們返回true,catch塊將執行。我可以想象F#這是否使用這樣的事情F#異常過濾器

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

但是,對我來說它編譯一貫的「捉[mscorlib程序] System.Object的」與到catch塊內部的過濾函數的調用,並沒有「過濾器「部分存在於生成的MSIL中。所以問題是,F#是否真的支持這個構造?

感謝

+1

爲什麼這個實現方式的內部對您來說很重要? –

+3

@JohnPalmer - 實現策略實際上影響了某些角落案例中的語義(由於.NET/Windows的兩遍模型),所以我認爲這是一個非常相關的問題。 – kvb

+0

VB.NET和F#有相似的條件捕獲結構,但是,VB.NET編譯器會發出_filter_ blocks,而F#顯然不會。這使得語義在某些情況下很重要,正如@kvb所說的,特別是在互操作性的情況下 – actionresult

回答

4

據我所知,F#實際上並不執行/使用/暴露filter提供MSIL處理器(ECMA-335,第5版,分區I,第12.4.2節「異常處理「)。根據F# 3.0 language specification的第6.9.21節,編譯器應該將整個with子句編譯爲catch塊;在編譯後的代碼中添加了一個「跌落」情況,以便如果捕獲的異常與with子句中的任何模式都不匹配,則會重新生成(通過rethrow IL指令)。這就是說,我真的很希望看到F#支持更多的低級IL/CLR結構 - 它們並不常用,但有時它們提供了正確實現某些東西的唯一方法,或者它們避免了需要對於複雜的解決方法;而且,正如OP的情況一樣,F#爲了互操作性的目的而支持這些是很重要的。例如,try...fault對於記錄目的來說確實非常方便,並且它將簡化當前需要使用附加邏輯(例如,在FSharp.Core中執行lock)的try...finally的一些代碼。

更新:我只是四處搜尋有關完全不同主題的信息,並從2006年的Don博客上跑過這篇文章:F# 1.1.13 now available!(也請參閱隨附的release notes)。當然,F#1.1.13是該語言的早期版本,在這一點上它仍然是相當實驗性的,但有趣的是編譯器曾經有一個--generate-filter-blocks開關。