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

Class 使用F在显式对象构造函数中使用failwith#,class,object,types,f#,constructor,Class,Object,Types,F#,Constructor,下面的代码 type A (b) = new () = if true then A 4. else failwith "" 给出一个错误: 这不是有效的对象构造表达式。显式对象构造函数必须调用备用构造函数或初始化对象的所有字段,并指定对超类构造函数的调用 type A (b) = static member Create() = if true then failwith "" else A(4.0) 这项工作: type A (b) = new

下面的代码

type A (b) =
  new () =
    if true then A 4.
    else failwith ""
给出一个错误:

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

type A (b) =
  static member Create() =
    if true then failwith ""
    else A(4.0)
这项工作:

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

简单的问题。构造函数中的
failwith
有什么不好的地方?

您看到的问题不是特定于
failwith
;除了构造函数调用之外,它还会出现在
A
类型的任何其他表达式中,例如
Unchecked.defaultof
。正如错误消息所指出的,构造函数对可在其内部使用的表达式的种类有限制,以确保类型始终被正确初始化

正如我在对Daniel回答的评论中提到的,如果你想在某些情况下快速失败,你可以采取如下措施:

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

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

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

这里有一种重做代码的方法:

type A (b) =
  new () = A(4.0) then 
    if true then failwith ""
然后
就像非主构造函数中的
do
绑定一样

有关更多选项,请参见上的MSDN页

编辑 kvb对于具有副作用的主要构造函数提出了一个很好的观点。如果是这样的话,你可能想考虑把你的逻辑移动到静态方法。这使得在调用构造函数之前可以完成其他工作

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

我喜欢您的解决方法,但首先抛出,然后调用主构造函数(以防构造函数有副作用)可能是有意义的。您实际上可以在构造函数中使用我建议的顺序,而不仅仅是静态方法:
如果为true,则failwith“”
在一行,然后是
A4.
在下一行。Oldrich在他的问题中提到这是一个可行的方法。我想我可能会提到使用静态方法,因为它使流程更加明显(IMO)。我喜欢只在重载时使用额外的构造函数。我在问题中没有看到它,但也许我只是缺少了一些东西。。。在他的示例中,他使用
if/then/else
,而不是
if/then
,并在两个分支中调用构造函数。True。我把两者等同起来。在您的答案中添加一个示例可能是值得的,因为您的方法使副作用在转发到另一个构造函数之前更为明显。我记得当我第一次发现它时,我非常感激,因为在C#中做类似的事情需要一个静态方法,等等,绝对值得一提。