【问题标题】:F# exception filtersF# 异常过滤器
【发布时间】:2013-09-04 15:05:38
【问题描述】:

文章https://devblogs.microsoft.com/dotnet/the-good-and-the-bad-of-exception-filters/ 建议 F# 原生支持异常过滤器(例如,在 C# 中没有语法)。异常过滤器适当的catch块之前运行,如果它们返回true,catch块将执行。我会想象 F# 使用类似这样的东西来做到这一点

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

但是,对我来说,它通过调用 catch 块内的过滤器函数编译为通常的“catch [mscorlib]System.Object”,并且生成的 MSIL 中不存在“过滤器”部分。那么问题来了,F# 真的支持这种结构吗?

谢谢

【问题讨论】:

  • 为什么这种实现方式的内部结构对您很重要?
  • @JohnPalmer - 实施策略实际上会影响某些极端情况下的语义(由于 .NET/Windows 的两次传递模型),所以我认为这是一个非常相关的问题。
  • VB.NET 和 F# 具有相似的条件 catch 构造,但是,VB.NET 编译器发出 filter 块,而 F# 显然没有。正如@kvb 所说,这使得语义很重要,在某些情况下,尤其是互操作

标签: exception f# clr


【解决方案1】:

据我所知,F# 实际上并没有实现/使用/公开 MSIL 中可用的 filter 处理程序(ECMA-335,第 5 版,Partition I,第 12.4.2 节“异常处理”)。根据F# 3.0 language specification 的第6.9.21 节,编译器应该将整个with 子句编译成catch 块;一个“fall-through”案例被添加到编译的代码中,因此如果捕获的异常与with 子句中的任何模式都不匹配,它会被重新引发(通过rethrow IL 指令)。

也就是说,我真的很希望看到 F# 支持更多的低级 IL/CLR 构造——它们不经常使用,但有时它们提供了正确实现某些东西的唯一方法,或者它们避免了对复杂的解决方法;并且,在 OP 的情况下,F# 支持这些以实现互操作性很重要。例如,try...fault 对于日志记录非常方便,它可以简化当前需要使用 try...finally 和附加逻辑的一些代码(例如,FSharp.Core 中的 lock 的实现)。

更新:我只是在四处寻找有关完全不同主题的信息,并在 Don 的博客上看到了 2006 年的这篇文章:F# 1.1.13 now available!(另请参阅随附的 release notes)。当然,F# 1.1.13 是该语言的非常早期版本,当时它还处于试验阶段,但有趣的是,编译器曾经有一个 --generate-filter-blocks 开关。

【讨论】:

    猜你喜欢
    • 2011-05-15
    • 1970-01-01
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2011-04-03
    相关资源
    最近更新 更多