使用F#在显式对象构造函数中使用failwith

时间:2011-09-29 12:29:56

标签: class object types f# constructor

以下代码

type A (b) =
  new () =
    if true then A 4.
    else failwith ""

给出错误:

  

这不是有效的对象构造表达式。显式对象构造函数必须调用备用构造函数或初始化对象的所有字段,并指定对超类构造函数的调用。

这有效:

type A (b) =
  new () =
    if true then A 4.
    else failwith ""; A 4.

简单的问题。构造函数中failwith的坏处是什么?

2 个答案:

答案 0 :(得分:3)

问题本身不是failwith。如错误所示,非主要构造函数受到限制。这是为了鼓励将所有初始化逻辑放在主构造函数中。你的例子似乎是人为的。如果您展示了更多您正在尝试做的事情,也许有人可以提供解决方案。

这是重写代码的一种方法:

type A (b) =
  new () = A(4.0) then 
    if true then failwith ""

then在非主要构造函数中的行为类似于do

有关更多选项,请参阅Constructors上的MSDN页面。

修改

对于具有副作用的初级构建体,kvb提出了一个很好的观点。如果是这种情况,您可能需要考虑将逻辑移动到静态方法。这显然可以在调用构造函数之前完成其他工作。

type A (b) =
  static member Create() =
    if true then failwith ""
    else A(4.0)

答案 1 :(得分:2)

您看到的问题并非针对failwith;除了构造函数调用之外,它还会出现A类型的任何其他表达式,例如Unchecked.defaultof<A>。正如错误消息所示,构造函数对可在其中使用的表达式类型有限制,以确保始终正确地初始化类型。

正如我在Daniel的回答评论中所提到的,如果你想在某些情况下快速失败,你可以做类似的事情:

new() =
    if true then failwith ""
    A 4.0

这将在它有机会执行链式构造函数调用之前抛出异常。