覆盖Exception.Message / exception模式匹配

时间:2011-02-17 18:45:37

标签: exception f# pattern-matching

我正在尝试在其定义中对异常进行模式匹配。使用F#的异常语法可能会出现以下情况,或者我必须将Exception子类化为

这是我期望的工作:

exception CoordErr of int * int
    with
        override this.Message = 
            let CoordErr(x, y) = this
            sprintf "(%i %i)" x y //ERROR

但产生错误:

  

未定义值或构造函数“x”   值或构造函数“y”未定义

修改

我也尝试过添加parens:

let (CoordErr(x, y)) = this

但这会产生错误:

  

预计此表达式的类型为exn,但此处的类型为CoordErr

更新

以下作品,但并不理想:

exception CoordErr of int * int
    with
        override this.Message = 
            sprintf "(%i %i)" this.Data0 this.Data1

还有其他办法吗?

更新2

从kvb的回答中得到启示,我想我可以执行以下操作来吞下incomplete matches警告:

exception CoordErr of int * int
    with
        override this.Message = 
            match this :> exn with
            | CoordErr(x, y) -> sprintf "(%i %i)" x y
            | _ -> Unchecked.defaultof<_>

3 个答案:

答案 0 :(得分:4)

你的第一次尝试不起作用,因为你正在定义一个名为CoordErr的let-bound函数,它会影响异常构造函数,这不是你想要的。

你的第二次尝试几乎可行。遗憾的是,异常定义与被区分的联合不同:当与异常构造函数进行模式匹配时,您匹配的表达式必须是exn类型(而不是特定异常子类型)。在您的情况下,您尝试将this(类型为CoordErr)与CoordErr构造函数进行匹配。这是一个解决方法的原因吗?

exception CoordErr of int * int
    with
        override this.Message = 
          let (CoordErr(x,y)) = upcast this
          sprintf "(%i %i)" x y

答案 1 :(得分:2)

命名构造函数参数并访问相应的字段似乎有效:

exception CoordErr of x : int * y : int
    with
        override this.Message = 
            sprintf "(%i %i)" this.x this.y

我意识到这不是模式匹配解决方案,但它确实回答了问题的“Overriding Exception.Message”部分。 :)

答案 2 :(得分:0)

您可以使用try with expression

的异常识别模式匹配
exception CoordErr of int * int
    with
        override this.Message = 
            try raise this with CoordErr(x, y) -> sprintf "(%i %i)" x y